I have a numpy array of shape, say, (1000, 80) and I want to convert it to (100, 40, 2). You can think of it as having 1000 observations where the first 40 columns refer to a specific feature across 40 days and the next 40 columns to a 2nd feature across the same 40 days.
So, I want to the 2nd dimension to be the 40 days while the 3rd should be the values of these two features for each day.
Here's a simple example with what I tried:
import numpy as np
data = [[11, 22, 33, 44],
[55, 66, 77 ,88],
[99, 100, 101, 102]]
data = np.array(data)
# This works but I have to manually do it for every day
np.c_[data[:, ::2], data[:, 1::2]].reshape((3, 2, 2))
# This does not work
np.c_[data[:, i::2] for i in range(2)].reshape((3, 2, 2))
Desired output:
array([[[ 11, 33],
[ 22, 44]],
[[ 55, 77],
[ 66, 88]],
[[ 99, 101],
[100, 102]]])
You can reshape first and then transpose the second and third axis:
data.reshape(-1, 2, data.shape[1] / 2).transpose(0,2,1)
#array([[[ 11, 33],
# [ 22, 44]],
# [[ 55, 77],
# [ 66, 88]],
# [[ 99, 101],
# [100, 102]]])
Or swapaxes:
data.reshape(-1, 2, data.shape[1] / 2).swapaxes(1,2)
#array([[[ 11, 33],
# [ 22, 44]],
# [[ 55, 77],
# [ 66, 88]],
# [[ 99, 101],
# [100, 102]]])
Or as #wwii commented, reshape with column-major order:
data.reshape(-1, data.shape[1] / 2, 2, order='F')
Related
Supposing I have a matrix A with the np.shape(A) = (9,2,2).
Then, I would like to find the smallest element value for the inner matrix (2,2) of total 9 outer matrix. Let's call it B.
Could anyone let me know what is the numpy code, please?
Thank you in advance.
import numpy as np
A =np.array([[[24, 73],
[35, 67]],
[[35, 68],
[21, 5]],
[[29, 69],
[60, 46]],
[[98, 25],
[50, 92]],
[[63, 27],
[55, 28]],
[[60, 89],
[61, 66]],
[[87, 38],
[44, 33]],
[[64, 76],
[76, 70]],
[[90, 91],
[71, 58]]])
np.shape(A)
Expected Result
B = [24,5,29,25,27,60,38,64,58]
np.shape(B) = (9,)
Solution
import numpy as np
A =np.array([[[24, 73],
[35, 67]],
[[35, 68],
[21, 5]],
[[29, 69],
[60, 46]],
[[98, 25],
[50, 92]],
[[63, 27],
[55, 28]],
[[60, 89],
[61, 66]],
[[87, 38],
[44, 33]],
[[64, 76],
[76, 70]],
[[90, 91],
[71, 58]]])
B1 = A.min(axis=(1, 2))
B2 = np.min(A, axis=(1, 2))
print("B1 =", B1)
print("B2 =", B2)
print("np.shape(B1) =", np.shape(B1))
Find minimum value with 2 menthods
1.
B1 = A.min(axis=(1, 2))
2.
B2 = np.min(A, axis=(1, 2))
Find shape of array in numpy
shape = np.shape(B1)
Output
B1 = [24 5 29 25 27 60 33 64 58]
B2 = [24 5 29 25 27 60 33 64 58]
np.shape(B1) = (9,)
Use min aggregating on the last two axes:
A.min((1, 2))
Alternatively, if you want a generic code to handle any number of dimensions, reshape then aggregate the min on the last dimension:
A.reshape(A.shape[0], -1).min(-1)
Output: array([24, 5, 29, 25, 27, 60, 33, 64, 58])
Since you wish only the get the code, there you go:
np.min(A, axis=(1,2))
I'm quite new to numpy, I tried with vstack but it seems really wrong since it creates a copy in memory everytime.
The initial structure is:
[[1,2,3],
[1,2,3],
[1,2,3]]
and it will be mapped to:
[[[3,2,1,2], [4,5,2,7], [7,4,1,3]],
[[3,2,1,2], [4,5,2,7], [7,4,1,3]],
[[3,2,1,2], [4,5,2,7], [7,4,1,3]]]
The numbers here don't have any meaning, it's just to show the structure, basically each integer is decoded to a list of integers N -> [N_1, N_2, N_3, N_4]
For context I have pixels encoded in 32bits and I have to decode them to argb
Create uint8 view:
>>> ar = np.random.randint(0, 2 ** 31, (3, 3))
>>> ar
array([[ 437217537, 524850213, 771706759],
[ 467263015, 219221544, 1712453711],
[1444860139, 625411292, 1224272631]])
>>> ar[1:] = ar[0] # make the layout the same as the example of OP
>>> ar
array([[437217537, 524850213, 771706759],
[437217537, 524850213, 771706759],
[437217537, 524850213, 771706759]])
>>> ar.view(np.uint8).reshape(3, 3, -1)
array([[[ 1, 105, 15, 26],
[ 37, 148, 72, 31],
[135, 79, 255, 45]],
[[ 1, 105, 15, 26],
[ 37, 148, 72, 31],
[135, 79, 255, 45]],
[[ 1, 105, 15, 26],
[ 37, 148, 72, 31],
[135, 79, 255, 45]]], dtype=uint8)
>>> int.from_bytes(bytes(_[0, 0]), 'little') == ar[0, 0]
True
I have value X of type ndarray with shape: (40000, 2)
The second column of X contains list of 50 numbers
Example:
[17, [1, 2, 3, ...]],
[39, [44, 45, 45, ...]], ...
I want to convert it to ndarray of shape (40000, 51):
the first column will be the same
the every element of the list will be in it's own column.
for my example:
[17, 1, 2, 3, ....],
[39, 44, 45, 45, ...]
How can I do it ?
np.hstack((arr[:,0].reshape(-1,1), np.array(arr[:,1].tolist())))
Example:
>>> arr
array([[75, list([90, 39, 63])],
[20, list([82, 92, 22])],
[80, list([12, 6, 89])],
[79, list([11, 96, 74])],
[96, list([26, 37, 65])]], dtype=object)
>>> np.hstack((arr[:,0].reshape(-1,1),np.array(arr[:,1].tolist()))).astype(int)
array([[75, 90, 39, 63],
[20, 82, 92, 22],
[80, 12, 6, 89],
[79, 11, 96, 74],
[96, 26, 37, 65]])
You can do this for each line of your ndarray , here is an example :
# X = [39, [44, 45, 45, ...]]
newX = numpy.ndarray(shape=(1,51))
new[0] = X[0] # adding the first element
# now the rest of elements
i = 0
for e in X[1] :
newX[i] = e
i = i + 1
You can make this process as a function and apply it in this way :
newArray = numpy.ndarray(shape=(40000,51))
i = 0
for x in oldArray :
Process(newArray[i],x)
i=i+1
I defined the source array (with shorter lists in column 1) as:
X = np.array([[17, [1, 2, 3, 4]], [39, [44, 45, 45, 46]]])
To do your task, define the following function:
def myExplode(row):
tbl = [row[0]]
tbl.extend(row[1])
return tbl
Then apply it to each row:
np.apply_along_axis(myExplode, axis=1, arr=X)
The result is:
array([[17, 1, 2, 3, 4],
[39, 44, 45, 45, 46]])
I'm having a hard time phrasing what I want, which is why I didn't find it on Google. Let me start with an example before formulating the general case.
Say we have 7 arrays a1, ..., a7, each of shape (4, 5). I want a new array where the 7 arrays are arranged like this:
a1 a2 a3
a4 a5 a6
a7 0 0
This array is of shape (3*4, 3*5) == (12, 15), 0 is np.zeros((4, 5)).
In general, I have C arrays a1, ..., aC, of shape (H, W), and I want to put them into an array of shape (h*H, w*W), where h = ceil(sqrt(C)) and w = ceil(C/h). The C arrays are stored as one (C, H, W) dimensional array.
What's the most elegant way to do this? I was hacking something together by iterating over the necessary indices but it's not nice so I stopped.
Speed is not top priority and the arrays are fairly small.
Approach #1
Some permuting of axes and reshaping should do the job -
C,m,n = a.shape
h = int(np.ceil(np.sqrt(C)))
w = int(np.ceil(C/h))
out = np.zeros((h,w,m,n),dtype=a.dtype)
out.reshape(-1,m,n)[:C] = a
out = out.swapaxes(1,2).reshape(-1,w*n)
Sample input, output -
In [340]: a
Out[340]:
array([[[55, 58],
[75, 78]],
[[78, 20],
[94, 32]],
[[47, 98],
[81, 23]],
[[69, 76],
[50, 98]],
[[57, 92],
[48, 36]],
[[88, 83],
[20, 31]],
[[91, 80],
[90, 58]]])
In [341]: out
Out[341]:
array([[55, 58, 78, 20, 47, 98],
[75, 78, 94, 32, 81, 23],
[69, 76, 57, 92, 88, 83],
[50, 98, 48, 36, 20, 31],
[91, 80, 0, 0, 0, 0],
[90, 58, 0, 0, 0, 0]])
Approach #2
Simpler one with zeros-concatenation -
z = np.zeros((h*w-C,m,n),dtype=a.dtype)
out = np.concatenate((a,z)).reshape(h,w,m,n).swapaxes(1,2).reshape(-1,w*n)
That could be modified/simplified a bit by using zeros-padding with np.pad -
zp = np.pad(a,((0,h*w-C),(0,0),(0,0)),'constant')
out = zp.reshape(h,w,m,n).swapaxes(1,2).reshape(-1,w*n)
I have two arrays A and B in numpy. A holds cartesian coordinates, each row is one point in 3D space and has the shape (r, 3). B has the shape (r, n) and holds integers.
What I would like to do is multiply each element of B with each row in A, so that the resulting array has the shape (r, n, 3). So for example:
# r = 3
A = np.array([1,1,1, 2,2,2, 3,3,3]).reshape(3,3)
# n = 2
B = np.array([10, 20, 30, 40, 50, 60]).reshape(3,2)
# Result with shape (3, 2, 3):
# [[[10,10,10], [20,20,20]],
# [[60,60,60], [80,80,80]]
# [[150,150,150], [180,180,180]]]
I'm pretty sure this can be done with np.einsum, but I've been trying this for quite a while now and can't get it to work.
Use broadcasting -
A[:,None,:]*B[:,:,None]
Since np.einsum also supports broadcasting, you can use that as well (thanks to #ajcr for suggesting this concise version) -
np.einsum('ij,ik->ikj',A,B)
Sample run -
In [22]: A
Out[22]:
array([[1, 1, 1],
[2, 2, 2],
[3, 3, 3]])
In [23]: B
Out[23]:
array([[10, 20],
[30, 40],
[50, 60]])
In [24]: A[:,None,:]*B[:,:,None]
Out[24]:
array([[[ 10, 10, 10],
[ 20, 20, 20]],
[[ 60, 60, 60],
[ 80, 80, 80]],
[[150, 150, 150],
[180, 180, 180]]])
In [25]: np.einsum('ijk,ij->ijk',A[:,None,:],B)
Out[25]:
array([[[ 10, 10, 10],
[ 20, 20, 20]],
[[ 60, 60, 60],
[ 80, 80, 80]],
[[150, 150, 150],
[180, 180, 180]]])