Numpy Multidimensional Array - python

I'm new to numpy, I don't understand how the following works:
np.array([range(i, i + 3) for i in [2, 4, 6]])
and the output is:
array([[2, 3, 4],[4, 5, 6],[6, 7, 8]])

Do you understand list comprehensions? range?
In [12]: [range(i, i + 3) for i in [2, 4, 6]]
Out[12]: [range(2, 5), range(4, 7), range(6, 9)]
np.array converts the range objects to lists, and then builds the array.
In [13]: [list(range(i, i + 3)) for i in [2, 4, 6]]
Out[13]: [[2, 3, 4], [4, 5, 6], [6, 7, 8]]
In [14]: np.array([list(range(i, i + 3)) for i in [2, 4, 6]])
Out[14]:
array([[2, 3, 4],
[4, 5, 6],
[6, 7, 8]])
So basically it's just a variation on the textbook example of making an array from a list of lists:
In [15]: np.array([[1,2,3],[10,11,12]])
Out[15]:
array([[ 1, 2, 3],
[10, 11, 12]])

Related

Concatenate the nested arrays within a single 2d array, element-wise [duplicate]

This question already has answers here:
Transpose list of lists
(14 answers)
Closed last year.
I have a numpy array like this:
array = [[1, 3, 5, 7], [2, 4, 6, 8]]
I would like to concatenate them element-wise. Most of the solutions I have found are able to do this with two separate 2d arrays, but I would like to do this within a single 2d array.
Desired output:
array = [[1, 2], [3, 4], [5, 6], [7, 8]]
Just only line code
array = [[1, 3, 5, 7], [2, 4, 6, 8]]
print(list(zip(*array)))
output :
[(1, 2), (3, 4), (5, 6), (7, 8)]
ljdyer is almost right, but you have only one array, so you can do this:
list(zip(*array))
This is a zip operation. Try:
arr1 = [1, 3, 5, 7]
arr2 = [2, 4, 6, 8]
print(list(zip(arr1,arr2)))
Output:
[(1, 2), (3, 4), (5, 6), (7, 8)]
Or for numpy arrays you have the stack operation:
import numpy as np
a = np.array([1, 3, 5, 7])
b = np.array([2, 4, 6, 8])
c = np.stack((a,b), axis = 1)
print(c)
See https://www.delftstack.com/howto/numpy/python-numpy-zip/
The following code will concatenate array element wise in each column
import numpy as np
array = np.array([[1, 3, 5, 7], [2, 4, 6, 8]])
res = []
for i in range(array.shape[1]):
res.append(array[:, i])
res = np.array(res)
print(res.tolist())
Numpy transpose:
In [382]: np.transpose([[1, 3, 5, 7], [2, 4, 6, 8]])
Out[382]:
array([[1, 2],
[3, 4],
[5, 6],
[7, 8]])
If it already is a numpy array (as opposed to just a list of lists),you can use the T shortcut:
In [383]: arr = np.array([[1, 3, 5, 7], [2, 4, 6, 8]])
In [384]: arr
Out[384]:
array([[1, 3, 5, 7],
[2, 4, 6, 8]])
In [385]: arr.T
Out[385]:
array([[1, 2],
[3, 4],
[5, 6],
[7, 8]])
list-zip is a well known list version of transpose:
In [386]: list(zip(*arr))
Out[386]: [(1, 2), (3, 4), (5, 6), (7, 8)]
Note the result is a list of tuples.

How to create a 2D array as rewrite code for the array.reshape() method

I'm trying to create function of converting array B to array of other shape in equal q-ty of elements.
B = np.array([[2, 4, 6], [4, 8, 10]])
to array([[2, 4],[6, 4],[8, 10]])
def my_reshape (A, m, n):
A_ravel = A.ravel()
A_list = [i for i in A_ravel]
print(A_list)
print(len(A_list))
if m*n == len(A_list):
for elem in A_list:
A_shape = [[elem for j in range(n)] for i in range(m)]
else:
print('Q-ty', m*n, ' - doesn't match to q-ty of list)
A_shape = []
return np.array(A_shape)
But it takes only the last element = 10, instead of each of list?
OUT:
[2, 4, 6, 4, 8, 10]
array([[10, 10],
[10, 10],
[10, 10]])
It has to be
array([[2, 4],
[6, 4],
[8, 10]]
2 way
def my_reshape2 (A, m, n):
for elem in A_list:
array= []
for j in range(m):
temp=[]
for i in range(n):
temp.append(i)
array.append(temp)
return array
OUT: [[0, 1], [0, 1], [0, 1]]
How I have to code for taking elements in A to new array?
In [99]: B = np.array([[2, 4, 6], [4, 8, 10]])
In [100]: B
Out[100]:
array([[ 2, 4, 6],
[ 4, 8, 10]])
target:
In [101]: np.array([[2, 4],[6, 4],[8, 10]])
Out[101]:
array([[ 2, 4],
[ 6, 4],
[ 8, 10]])
simple reshape:
In [102]: B.reshape(3,2)
Out[102]:
array([[ 2, 4],
[ 6, 4],
[ 8, 10]])
reshape says it essentially ravels the array, and then makes a new one with the new shape:
In [103]: B.ravel()
Out[103]: array([ 2, 4, 6, 4, 8, 10])
Your target keeps the ravelled elements in the same order. There's no need to do any rearranging.
Doing the same thing with lists is more work.
Nested lists have an easy transpose like operation:
In [104]: B.tolist()
Out[104]: [[2, 4, 6], [4, 8, 10]]
In [105]: list(zip(*B.tolist()))
Out[105]: [(2, 4), (4, 8), (6, 10)]
In [106]: B.T
Out[106]:
array([[ 2, 4],
[ 4, 8],
[ 6, 10]])
but you don't want that.
The fast way to get your A_list is
In [107]: B.ravel().tolist()
Out[107]: [2, 4, 6, 4, 8, 10]
and one way of collecting 3 lists of 2 from that is:
In [112]: B_list = B.ravel().tolist()
In [113]: [[i,j] for i,j in zip(B_list[::2], B_list[1::2])]
Out[113]: [[2, 4], [6, 4], [8, 10]]
To simulate the effect of reshape, you can make a copy of the data into another array of the correct shape:
B = np.array([[2, 4, 6], [4, 8, 10]])
output = np.empty((3, 2), dtype=B.dtype)
output.ravel()[:] = B.ravel()[:]
Since ravel pretty much always returns a view for simple (contiguous) arrays, the result is as expected:
>>> output
array([[ 2, 4],
[ 6, 4],
[ 8, 10]])

Concatenate indices of each Numpy Array in a Matrix

So I have a Numpy Array with a bunch of numpy arrays inside of them. I want to group them based on the position in their individual array.
For Example:
If Matrix is:
[[1, 2], [2, 3], [4, 5], [6, 7]]
Then the code should return:
[[1, 2, 4, 6], [2, 3, 5, 7]]
This is becuase 1, 2, 4, 6 are all the first elements in their individual arrays, and 2, 3, 5, 7 are the second elements in their individual arrays.
Anyone know some function that could do this. Thanks.
Answer in Python.
Using numpy transpose should do the trick:
a = np.array([[1, 2], [2, 3], [4, 5], [6, 7]])
a_t = a.T
print(a_t)
array([[1, 2, 4, 6],
[2, 3, 5, 7]])
Your data as a list:
In [101]: alist = [[1, 2], [2, 3], [4, 5], [6, 7]]
In [102]: alist
Out[102]: [[1, 2], [2, 3], [4, 5], [6, 7]]
and as a numpy array:
In [103]: arr = np.array(alist)
In [104]: arr
Out[104]:
array([[1, 2],
[2, 3],
[4, 5],
[6, 7]])
A standard idiom for 'transposing' lists is:
In [105]: list(zip(*alist))
Out[105]: [(1, 2, 4, 6), (2, 3, 5, 7)]
with arrays, there's a transpose method:
In [106]: arr.transpose()
Out[106]:
array([[1, 2, 4, 6],
[2, 3, 5, 7]])
The first array is (4,2) shape; its transpose is (2,4).

Insert 1D NumPy array as column in existing 2D array

I have a 2D NumPy array:
>>> import numpy as np
>>> a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
>>> a
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
and a 1D array:
>>> b = np.arange(3)
>>> b
array([0, 1, 2])
Is there an elegant way to insert b into a as a new first column?
So that:
>>> a
array([[0, 1, 2, 3],
[1, 4, 5, 6],
[2, 7, 8, 9]])
You could use column_stack()
In [256]: np.column_stack((b, a))
Out[256]:
array([[0, 1, 2, 3],
[1, 4, 5, 6],
[2, 7, 8, 9]])

Numpy: equivalent of numpy.roll but only for data visualisation

Is there a way to perform a roll on an array, but instead of having a copy of the data having just a different visualisation of it?
An example might clarify: given b a rolled version of a...
>>> a = np.random.randint(0, 10, (3, 3))
>>> a
array([[6, 7, 4],
[5, 4, 8],
[1, 3, 4]])
>>> b = np.roll(a, 1, axis=0)
>>> b
array([[1, 3, 4],
[6, 7, 4],
[5, 4, 8]])
...if I perform an assignment on array b...
>>> b[2,2] = 99
>>> b
array([[ 1, 3, 4],
[ 6, 7, 4],
[ 5, 4, 99]])
...the content of a won't change...
>>> a
array([[6, 7, 4],
[5, 4, 8],
[1, 3, 4]])
...contrarily, I would like to have:
>>> a
array([[6, 7, 4],
[5, 4, 99], # observe as `8` has been changed here too!
[1, 3, 4]])
Thanks in advance for your time and expertise!
This is not possible, sorry. The rolled array cannot be described by a different set of strides, which would be necessary for a NumPy view to work.

Categories

Resources