Given a numpy array of size (n,) how do you transform it to a numpy array of size (n,1).
The reason is because I am trying to matrix multiply to numpy arrays of size (n,) and (,n) to get a (n,n) but when I do:
numpy.dot(a,b.T)
It says that you can't do it. I know as a fact that transposing a (n,) does nothing, so it would just be nice to change the (n,) and make them (n,1) and avoid this problem all together.
Use reshape (-1,1) to reshape (n,) to (n,1), see detail examples:
In [1]:
import numpy as np
A=np.random.random(10)
In [2]:
A.shape
Out[2]:
(10,)
In [3]:
A1=A.reshape(-1,1)
In [4]:
A1.shape
Out[4]:
(10, 1)
In [5]:
A.T
Out[5]:
array([ 0.6014423 , 0.51400033, 0.95006413, 0.54321892, 0.2150995 ,
0.09486603, 0.54560678, 0.58036358, 0.99914564, 0.09245124])
In [6]:
A1.T
Out[6]:
array([[ 0.6014423 , 0.51400033, 0.95006413, 0.54321892, 0.2150995 ,
0.09486603, 0.54560678, 0.58036358, 0.99914564, 0.09245124]])
You can use None for dimensions that you want to be treated as degenerate.
a = np.asarray([1,2,3])
a[:]
a[:, None]
In [48]: a
Out[48]: array([1, 2, 3])
In [49]: a[:]
Out[49]: array([1, 2, 3])
In [50]: a[:, None]
Out[50]:
array([[1],
[2],
[3]])
Related
If I have a MxN numpy array denoted arr, I wish to index over all elements and adjust the values like so
for m in range(arr.shape[0]):
for n in range(arr.shape[1]):
arr[m, n] += x**2 * np.cos(m) * np.sin(n)
Where x is a random float.
Is there a way to broadcast this over the entire array without needing to loop? Thus, speeding up the run time.
You are just adding zeros, because sin(2*pi*k) = 0 for integer k.
However, if you want to vectorize this, the function np.meshgrid could help you.
Check the following example, where I removed the 2 pi in the trigonometric functions to add something unequal zero.
x = 2
arr = np.arange(12, dtype=float).reshape(4, 3)
n, m = np.meshgrid(np.arange(arr.shape[1]), np.arange(arr.shape[0]), sparse=True)
arr += x**2 * np.cos(m) * np.sin(n)
arr
Edit: use the sparse argument to reduce memory consumption.
You can use nested generators of two-dimensional arrays:
import numpy as np
from random import random
x = random()
n, m = 10,20
arr = [[x**2 * np.cos(2*np.pi*j) * np.sin(2*np.pi*i) for j in range(m)] for i in range(n)]
In [156]: arr = np.ones((2, 3))
Replace the range with arange:
In [157]: m, n = np.arange(arr.shape[0]), np.arange(arr.shape[1])
And change the first array to (2,1) shape. A (2,1) array broadcasts with a (3,) to produce a (2,3) result.
In [158]: A = 0.23**2 * np.cos(m[:, None]) * np.sin(n)
In [159]: A
Out[159]:
array([[0. , 0.04451382, 0.04810183],
[0. , 0.02405092, 0.02598953]])
In [160]: arr + A
Out[160]:
array([[1. , 1.04451382, 1.04810183],
[1. , 1.02405092, 1.02598953]])
The meshgrid suggested in the accepted answer does the same thing:
In [161]: np.meshgrid(m, n, sparse=True, indexing="ij")
Out[161]:
[array([[0],
[1]]),
array([[0, 1, 2]])]
This broadcasting may be clearer with:
In [162]: m, n
Out[162]: (array([0, 1]), array([0, 1, 2]))
In [163]: m[:, None] * 10 + n
Out[163]:
array([[ 0, 1, 2],
[10, 11, 12]])
In MATLAB, one would simply say
L = 2^8
x = (-L/2:L/2-1)';
Which creates an array of size L X 1.
How might I create this in Python?
I tried:
L = 2**8
x = np.arange(-L/2.0,L/ 2.0)
Which doesn't work.
Here you go:
x.reshape((-1,1))
The MATLAB code produces a (1,n) size matrix, which is transposed to (n,1)
>> 2:5
ans =
2 3 4 5
>> (2:5)'
ans =
2
3
4
5
MATLAB matrices are always 2d (or higher). numpy arrays can be 1d or even 0d.
https://numpy.org/doc/stable/user/numpy-for-matlab-users.html
In numpy:
arange produces a 1d array:
In [165]: np.arange(2,5)
Out[165]: array([2, 3, 4])
In [166]: _.shape
Out[166]: (3,)
There are various ways of adding a trailing dimension to the array:
In [167]: np.arange(2,5)[:,None]
Out[167]:
array([[2],
[3],
[4]])
In [168]: np.arange(2,5).reshape(3,1)
Out[168]:
array([[2],
[3],
[4]])
numpy has a transpose, but its behavior with 1d arrays is not what people expect from a 2d array. It's actually more powerful and general than MATLAB's '.
I want to reverse reshaped numpy by calling reshape again on the array to reshape it into the original dimensions.
I have an array trian_x with dimensions (x, y, z) then I reshape train_x
train_X_1 = train_X.reshape(train_X.shape[0], train_X.shape[1] * train_X.shape[2])
then I want to reverse the reshaped
train_X_2 = train_X_1.reshape((train_X.shape[0], train_X.shape[1], train_X.shape[2])
when I compare
print((train_X_2 == train_X).all())
I get False
what's wrong with my code? thanks
Are you just trying this:
In [184]: x = np.arange(24).reshape(2,3,4)
In [185]: x1 = x.reshape(2,12)
In [186]: x2 = x1.reshape(2,3,4)
In [187]: np.allclose(x,x2)
Out[187]: True
What's your dtype? allclose is better for floats.
In [218]: data = np.load('../Downloads/train_X.npy')
In [219]: data.shape
Out[219]: (97848, 20, 2)
In [220]: data.dtype
Out[220]: dtype('float64')
In [221]: data1 = data.reshape(data.shape[0], data.shape[1]*data.shape[2])
In [222]: data1.shape
Out[222]: (97848, 40)
In [223]: data2 = data1.reshape(data.shape)
In [224]: data2.shape
Out[224]: (97848, 20, 2)
In [225]: np.allclose(data, data2)
Out[225]: False
In [226]: np.max(np.abs(data - data2))
Out[226]: nan
In [247]: np.isnan(data).sum()
Out[247]: 2514
In [248]: np.isnan(data2).sum()
Out[248]: 2514
There's your problem - the array contains nan, which don't test ==. Let's compare without those nan:
In [251]: np.allclose(np.nan_to_num(data),np.nan_to_num(data2))
Out[251]: True
It sounds like you want to flatten, then reverse, then reshape.
starting with an array:
import numpy as np
arr = np.arange(6).reshape((2,3)) #[[0, 1, 2,], [3, 4, 5]]
We can flatten into a 1D array using ravel
arr = arr.ravel() #[0,1,2,3,4,5]
We can then reverse the order
arr = arr[::-1] #[5,4,3,2,1,0]
Then we reshape it
arr.reshape(2,3) #[[5, 4, 3], [2, 1, 0]]
Altogether:
import numpy as np
arr = np.arange(6).reshape((2,3))
arr = arr.ravel()[::-1].reshape(2,3)
print(arr)
I'm trying to insert elements to an empty 2d numpy array. However, I am not getting what I want.
I tried np.hstack but it is giving me a normal array only. Then I tried using append but it is giving me an error.
Error:
ValueError: all the input arrays must have same number of dimensions
randomReleaseAngle1 = np.random.uniform(20.0, 77.0, size=(5, 1))
randomVelocity1 = np.random.uniform(40.0, 60.0, size=(5, 1))
randomArray =np.concatenate((randomReleaseAngle1,randomVelocity1),axis=1)
arr1 = np.empty((2,2), float)
arr = np.array([])
for i in randomArray:
data = [[170, 68.2, i[0], i[1]]]
df = pd.DataFrame(data, columns = ['height', 'release_angle', 'velocity', 'holding_angle'])
test_y_predictions = model.predict(df)
print(test_y_predictions)
if (np.any(test_y_predictions == 1)):
arr = np.hstack((arr, np.array([i[0], i[1]])))
arr1 = np.append(arr1, np.array([i[0], i[1]]), axis=0)
print(arr)
print(arr1)
I wanted to get something like
[[1.5,2.2],
[3.3,4.3],
[7.1,7.3],
[3.3,4.3],
[3.3,4.3]]
However, I'm getting
[56.60290125 49.79106307 35.45102444 54.89380834 47.09359271 49.19881675
22.96523274 44.52753514 67.19027156 54.10421167]
The recommended list append approach:
In [39]: alist = []
In [40]: for i in range(3):
...: alist.append([i, i+10])
...:
In [41]: alist
Out[41]: [[0, 10], [1, 11], [2, 12]]
In [42]: np.array(alist)
Out[42]:
array([[ 0, 10],
[ 1, 11],
[ 2, 12]])
If we start with a empty((2,2)) array:
In [47]: arr = np.empty((2,2),int)
In [48]: arr
Out[48]:
array([[139934912589760, 139934912589784],
[139934871674928, 139934871674952]])
In [49]: np.concatenate((arr, [[1,10]],[[2,11]]), axis=0)
Out[49]:
array([[139934912589760, 139934912589784],
[139934871674928, 139934871674952],
[ 1, 10],
[ 2, 11]])
Note that empty does not mean the same thing as the list []. It's a real 2x2 array, with 'unspecified' values. And those values remain when we add other arrays to it.
I could start with an array with a 0 dimension:
In [51]: arr = np.empty((0,2),int)
In [52]: arr
Out[52]: array([], shape=(0, 2), dtype=int64)
In [53]: np.concatenate((arr, [[1,10]],[[2,11]]), axis=0)
Out[53]:
array([[ 1, 10],
[ 2, 11]])
That looks more like the list append approach. But why start with the (0,2) array in the first place?
np.concatenate takes a list of arrays (or lists that can be made into arrays). I used nested lists that make (1,2) arrays. With this I can join them on axis 0.
Each concatenate makes a new array. So if done iteratively it is more expensive than the list append.
np.append just takes 2 arrays and does a concatenate. So doesn't add much. hstack tweaks shapes and joins on the 2nd (horizontal) dimension. vstack is another variant. But they all end up using concatenate.
With the hstack method, you can just reshape after you get the final array:
arr = arr.reshape(-1, 2)
print(arr)
The other method can be more easily done in a similar way:
arr1 = np.append(arr1, np.array([i[0], i[1]]) # in the loop
arr1 = arr1.reshape(-1, 2)
print(arr1)
I am trying to use numpy.where with csr_matrix, which dose not work. I am asking is there some built in function equivalent to numpy.where for sparse matrix. Here is an example of what I would like to do without using Forloop or .todense()
import scipy.sparse as spa
import numpy as np
N = 100
A = np.zeros((N,N))
di = np.diag_indices((len(A[:,0])))
A[di] = 2.3
'''
adding some values to non-diagonal terms
for sake of example
'''
for k in range(0,len(A)-1):
for j in range(-1,3,2):
A[k,k+j] = 4.0
A[2,3] =0.1
A[3,3] = 0.1
A[0,4] = 0.2
A[0,2] = 3
'''
creating sparse matrix
'''
A = spa.csc_matrix((N,N))
B = spa.csc_matrix((N,N))
'''
Here I get
TypeError: unsupported operand type(s) for &: 'csc_matrix' and 'csc_matrix'
'''
ind1 = np.where((A>0.0) & (A<=1.0))
B[ind1] = (3.0-B[ind1])**5-6.0*(2.0-B[ind1])**5
How about working with underlying arrays for A and B, the data arrays
In [36]: ind2=np.where((A.data>0.0)&(A.data<=1.0))
In [37]: A.indices[ind2]
Out[37]: array([2, 3, 0])
In [38]: A.indptr[ind2]
Out[38]: array([28, 31, 37])
In [39]: A.data[ind2]
Out[39]: array([ 0.1, 0.1, 0.2])
In [41]: B.data[ind2]=(3.0-B.data[ind2])**5-6.0*(2.0-B.data[ind2])**5
In [42]: B.data[ind2]
Out[42]: array([ 56.54555, 56.54555, 58.7296 ])
To see what ind2 corresponds to in the dense version, convert the array to coo
In [53]: Ac=A.tocoo()
In [54]: (Ac.row[ind2], Ac.col[ind2])
Out[54]: (array([2, 3, 0]), array([3, 3, 4]))
where, for reference, the where on the dense array is:
In [57]: np.where((A.A>0.0) & (A.A<=1.0))
Out[57]: (array([0, 2, 3]), array([4, 3, 3]))
One important caution - working with A.data means you exclude all of the zero entries of the dense array.