How do I convert an array of arrays into a multi-dimensional array in Python?
You can concatenate the arrays on a new axis. For example:
In [1]: a=np.array([1,2,3],dtype=object)
...: b=np.array([4,5,6],dtype=object)
To make an array of arrays we can't just combine them with array
, as the deleted answer did:
In [2]: l=np.array([a,b])
In [3]: l
Out[3]:
array([[1, 2, 3],
[4, 5, 6]], dtype=object)
In [4]: l.shape
Out[4]: (2, 3)
Instead we have to create an empty array of the right shape, and fill it:
In [5]: arr = np.empty((2,), object)
In [6]: arr[:]=[a,b]
In [7]: arr
Out[7]: array([array([1, 2, 3], dtype=object),
array([4, 5, 6], dtype=object)],
dtype=object)
np.stack
acts like np.array
, but uses concatenate
:
In [8]: np.stack(arr)
Out[8]:
array([[1, 2, 3],
[4, 5, 6]], dtype=object)
In [9]: _.astype(float)
Out[9]:
array([[ 1., 2., 3.],
[ 4., 5., 6.]])
We could also use concatenate
, hstack
or vstack
to combine the arrays on different axes. They all treat the array of arrays as a list of arrays.
If arr
is 2d (or higher) we have to ravel
it first.
How can I turn a flat list into a 2D array in python?
>>> import numpy as np
>>> np.array(data_list).reshape(-1, 2)
array([[0, 1],
[2, 3],
[4, 5],
[6, 7],
[8, 9]])
(The reshape
method returns a new "view" on the array; it doesn't copy the data.)
How to convert list of arrays into a multidimensional array
I don't believe there's anything built into the framework to do this - even Array.Copy
fails in this case. However, it's easy to write the code to do it by looping:
using System;
using System.Collections.Generic;
class Test
{
static void Main()
{
List<int[]> list = new List<int[]>
{
new[] { 1, 2, 3 },
new[] { 4, 5, 6 },
};
int[,] array = CreateRectangularArray(list);
foreach (int x in array)
{
Console.WriteLine(x); // 1, 2, 3, 4, 5, 6
}
Console.WriteLine(array[1, 2]); // 6
}
static T[,] CreateRectangularArray<T>(IList<T[]> arrays)
{
// TODO: Validation and special-casing for arrays.Count == 0
int minorLength = arrays[0].Length;
T[,] ret = new T[arrays.Count, minorLength];
for (int i = 0; i < arrays.Count; i++)
{
var array = arrays[i];
if (array.Length != minorLength)
{
throw new ArgumentException
("All arrays must be the same length");
}
for (int j = 0; j < minorLength; j++)
{
ret[i, j] = array[j];
}
}
return ret;
}
}
converty numpy array of arrays to 2d array
In response your comment question, let's compare 2 ways of creating an array
First make an array from a list of arrays (all same length):
In [302]: arr = np.array([np.arange(3), np.arange(1,4), np.arange(10,13)])
In [303]: arr
Out[303]:
array([[ 0, 1, 2],
[ 1, 2, 3],
[10, 11, 12]])
The result is a 2d array of numbers.
If instead we make an object dtype array, and fill it with arrays:
In [304]: arr = np.empty(3,object)
In [305]: arr[:] = [np.arange(3), np.arange(1,4), np.arange(10,13)]
In [306]: arr
Out[306]:
array([array([0, 1, 2]), array([1, 2, 3]), array([10, 11, 12])],
dtype=object)
Notice that this display is like yours. This is, by design a 1d array. Like a list it contains pointers to arrays elsewhere in memory. Notice that it requires an extra construction step. The default behavior of np.array
is to create a multidimensional array where it can.
It takes extra effort to get around that. Likewise it takes some extra effort to undo that - to create the 2d numeric array.
Simply calling np.array
on it does not change the structure.
In [307]: np.array(arr)
Out[307]:
array([array([0, 1, 2]), array([1, 2, 3]), array([10, 11, 12])],
dtype=object)
stack
does change it to 2d. stack
treats it as a list of arrays, which it joins on a new axis.
In [308]: np.stack(arr)
Out[308]:
array([[ 0, 1, 2],
[ 1, 2, 3],
[10, 11, 12]])
How to convert list of numpy arrays into single numpy array?
In general you can concatenate a whole sequence of arrays along any axis:
numpy.concatenate( LIST, axis=0 )
but you do have to worry about the shape and dimensionality of each array in the list (for a 2-dimensional 3x5 output, you need to ensure that they are all 2-dimensional n-by-5 arrays already). If you want to concatenate 1-dimensional arrays as the rows of a 2-dimensional output, you need to expand their dimensionality.
As Jorge's answer points out, there is also the function stack
, introduced in numpy 1.10:
numpy.stack( LIST, axis=0 )
This takes the complementary approach: it creates a new view of each input array and adds an extra dimension (in this case, on the left, so each n
-element 1D array becomes a 1-by-n
2D array) before concatenating. It will only work if all the input arrays have the same shape—even along the axis of concatenation.
vstack
(or equivalently row_stack
) is often an easier-to-use solution because it will take a sequence of 1- and/or 2-dimensional arrays and expand the dimensionality automatically where necessary and only where necessary, before concatenating the whole list together. Where a new dimension is required, it is added on the left. Again, you can concatenate a whole list at once without needing to iterate:
numpy.vstack( LIST )
This flexible behavior is also exhibited by the syntactic shortcut numpy.r_[ array1, ...., arrayN ]
(note the square brackets). This is good for concatenating a few explicitly-named arrays but is no good for your situation because this syntax will not accept a sequence of arrays, like your LIST
.
There is also an analogous function column_stack
and shortcut c_[...]
, for horizontal (column-wise) stacking, as well as an almost-analogous function hstack
—although for some reason the latter is less flexible (it is stricter about input arrays' dimensionality, and tries to concatenate 1-D arrays end-to-end instead of treating them as columns).
Finally, in the specific case of vertical stacking of 1-D arrays, the following also works:
numpy.array( LIST )
...because arrays can be constructed out of a sequence of other arrays, adding a new dimension to the beginning.
Converting a list of lists into a 2D numpy array
If your lists are NOT of the same length (in each nested dimension) you CANT do a traditional conversion to a NumPy array because it's necessary for a NumPy array of 2D or above to have the same number of elements in its first dimension.
So you cant convert [[1,2],[3,4,5]]
to a numpy array directly. Applying np.array
will give you a 2 element numpy array where each element is a list object as - array([list([1, 2]), list([3, 4, 5])], dtype=object)
. I believe this is the issue you are facing.
You cant create a 2D matrix for example that looks like -
[[1,2,3,?],
[4,5,6,7]]
What you may need to do is pad the elements of each list of lists of lists to a fixed length (equal lengths for each dimension) before converting to a NumPy array.
I would recommend iterating over each of the lists of lists of lists as done in the code I have written below to flatten your data, then transforming it the way you want.
If your lists are of the same length, then should not be a problem with numpy version 1.18.5
or above.
a = [[[1,2],[3,4]],[[5,6],[7,8]]]
np.array(a)
array([[[1, 2],
[3, 4]],
[[5, 6],
[7, 8]]])
However, if you are unable to still work with the list of list of lists, then you may need to iterate over each element first to flatten the list and then change it into a numpy array with the required shape as below -
a = [[[1,2],[3,4]],[[5,6],[7,8]]]
flat_a = [item for sublist in a for subsublist in sublist for item in subsublist]
np.array(flat_a).reshape(2,2,2)
array([[[1, 2],
[3, 4]],
[[5, 6],
[7, 8]]])
How can I convert a list to a multi-dimensional array?
No. In fact, these aren't necessarily compatible arrays.
[,]
defines a multidimensional array. List<List<T>>
would correspond more to a jagged array ( object[][]
).
The problem is that, with your original object, each List<object>
contained in the list of lists can have a different number of objects. You would need to make a multidimensional array of the largest length of the internal list, and pad with null values or something along those lines to make it match.
Numpy list of 1D Arrays to 2D Array
You can use
numpy.stack(arrays, axis=0)
if you have an array of arrays. You can specify the axis in case you want to stack columns and not rows.
How to convert List of arrays to two dimensional array?
You're going to have to iterate and copy all of the strings individually. However, the raw type Array^
isn't that convenient to work with, so you'll need to do something about that.
Basically, what you need to do is this:
for (int outer = 0; outer < vList->Count; outer++)
{
arrayOfSomeSort^ innerArray = vList[outer];
for (int inner = 0; inner < innerArray.Length; inner++)
anArray[outer, inner] = innerArray[inner];
}
Depending on how the rest of the program is, and what objects are actually in the List, there are a few options on what to do. Here are the options I see, in order of preference.
- Instead of a
List<Array^>^
, havevList
be aList<array<String^>^>^
. If the List truly is a list of string arrays, then this option is probably the most correct. In this case,arrayOfSomeSort^
would bearray<String^>^
. - If
vList
can't change type, but it does indeed contain string arrays, then I'd have the local variableinnerArray
be of typearray<String^>^
, and do a cast as you pull it out ofvList
. - If the arrays in the list aren't string arrays, but instead are object arrays that happen to contain strings, then I'd have
array<Object^>^ innerArray
, and cast to that instead, and do a cast toString^
as you pull each string out ofinnerArray
. - If none of those is appropriate, then you can leave
innerArray
as typeArray^
. You'll need to call the explicit methodArray.GetValue(int)
instead of using the[]
indexer. As with the previous option, you'll need to cast each string as you pull it out of the inner array.
You've set the second dimension to 5 without checking the lengths of the inner arrays; I'm assuming you know something we don't, and are sure that there won't be anything larger than 5. If not, you'll need to iterate the list once to get the maximum array size, create the 2D array, and then copy the strings.
Related Topics
How to Validate Azure Ad Security Token
Check If a Value Is in an Array (C#)
Setting Datacontext in Xaml in Wpf
Sort Observablecollection<String> Through C#
Format Timespan Greater Than 24 Hour
This.Visible Is Not Working in Windows Forms
The Type of One of the Expressions in the Join Clause Is Incorrect in Entity Framework
Generic Method Executed with a Runtime Type
How to Execute Code That Is in a String
.Net Xml Serialization Gotchas
How to Implement a Never Ending Task. (Timers VS Task)
C# Rsa Encryption/Decryption with Transmission