I want to check if a numpy array is multidimensional or not?
V = [[ -7.94627203e+01 -1.81562235e+02 -3.05418070e+02 -2.38451033e+02][ 9.43740653e+01 1.69312771e+02 1.68545575e+01 -1.44450299e+02][ 5.61599000e+00 8.76135909e+01 1.18959245e+02 -1.44049237e+02]]
How can I do that in numpy?
Use the .ndim property of the ndarray:
>>> a = np.array([[ -7.94627203e+01, -1.81562235e+02, -3.05418070e+02, -2.38451033e+02],[ 9.43740653e+01, 1.69312771e+02, 1.68545575e+01, -1.44450299e+02],[ 5.61599000e+00, 8.76135909e+01, 1.18959245e+02, -1.44049237e+02]])
>>> a.ndim
2
In some cases, you should also add np.squeeze() to make sure there are no "empty" dimensions
>>> a = np.array([[1,2,3]])
>>> a.ndim
2
>>> a = np.squeeze(a)
>>> a .ndim
1
You can use .shape property too, which gives you a tuple containing the length of each dimension. Therefore, to get the dimension using .shape you could aswell call len() on the resulting tuple:
import numpy as np
a = np.array([1,2,3])
b = np.array([[1,2,3]])
c = np.array([[1,2,3],[2,4,6],[3,6,9]])
print("a={}".format(a))
print("a.shape: {}; len(a.shape): {}".format(a.shape, len(a.shape)))
print("b={}".format(b))
print("b.shape: {}; len(b.shape): {}".format(b.shape, len(b.shape)))
print(c)
print("c.shape: {}; len(c.shape): {}".format(c.shape, len(c.shape)))
Output:
a=[1 2 3]
a.shape: (3,); len(a.shape): 1
b=[[1 2 3]]
b.shape: (1, 3); len(b.shape): 2
[[1 2 3]
[2 4 6]
[3 6 9]]
c.shape: (3, 3); len(c.shape): 2
Related
I have two arrays, one of shape arr1.shape = (1000,2) and the other of shape arr2.shape = (100,).
I'd like to somehow multiply arr1[:,1]*arr2 where arr1[:,0] == arr2.index so that I get a final shape of arr_out.shape = (1000,). The first column of arr1 is essentially an id where the following condition holds true: set(arr1[:,0]) == set(i for i in range(0,100)), i.e. there is always at least one value index of arr2 found in arr1[:,0].
I can't quite see how to do this in the numpy library but feel there should be a way using numpy multiply, if there was a way to configure the where condition correctly?
I considered perhaps a dummy index dimension for arr2 might help?
A toy example can be produced with the following code snippet
arr2_length = 100
arr1_length = 1000
arr1 = np.column_stack(
(np.random.randint(0,arr2_length,(arr1_length)),
np.random.rand(arr1_length))
)
arr2 = np.random.rand(arr2_length)
# Doesn't work
arr2_b = np.column_stack((
np.arange(arr2_length),
np.random.rand(arr2_length)
))
# np.multiply(arr1[:,1],arr2_b[:,1], where=(arr1[:,0]==arr2_b[:,0]))
One sort of solution I had was to leverage a left join in Pandas to broadcast the smaller array to a same-lengthed array and then multiply, as follows:
df = pd.DataFrame(arr1).set_index(0).join(pd.DataFrame(arr2))
arr_out = (df[0]*df[1]).values
But I'd really like to understand if there's a native numpy way of doing this since I feel using dataframe joins for a multiplication isn't a very readable solution and possibly suffers from excess memory overhead.
Thanks for your help.
I believe this does exactly what you want:
indices, values = arr1[:,0].astype(int), arr1[:,1]
arr_out = values * arr2[indices]
Is this what you're looking for?
import numpy as np
arr1 = np.random.randint(1, 5, (10, 2))
arr2 = np.random.randint(1, 5, (5,))
arr2_sampled = arr2[arr1[:, 0]]
result = arr1[:, 1]*arr2_sampled
Output:
arr1 =
[[4 2]
[3 3]
[2 3]
[3 1]
[2 1]
[2 4]
[1 1]
[4 2]
[4 1]
[3 4]]
arr2 =
[4 1 2 1 2]
arr2_sampled =
[2 1 2 1 2 2 1 2 2 1]
result =
[4 3 6 1 2 8 1 4 2 4]
In matalb we can have a vector as a=[1,3,4] and use it to access and replace elements of another vector or matrix, like this.
a=[1,2,4];
b=[1,2,3,4];
b(a)=1
so b would be [1,1,3,1]
Is there anyway to do this in python?
I know I can do stuff like this:
a=[1,2,4]
b=list(range(1,10))
[b[x] for x in a]
but it doesn't alow me to replace the values, for example.
Numpy has similar functionality. However, keep in mind that Numpy indexing starts at 0. not at 1:
import numpy as np
a = np.array([1, 2, 4])
b = np.array([1, 2, 3, 4])
b[a - 1] = 1
print(b)
#[1 1 3 1]
you can also use logical indexing in python:
import numpy as np
a = np.array([1,1,1,0])
b = np.array([5,6,7,8])
b[a==True]=1
#[1 1 1 8]
After a for loop, I can not append each iteration into a single array:
in:
for a in l:
arr = np.asarray(a_lis)
print(arr)
How can I append and return in a single array the above three arrays?:
[[ 0.55133 0.58122 0.66129032 0.67562724 0.69354839 0.70609319
0.6702509 0.63799283 0.61827957 0.6155914 0.60842294 0.60215054
0.59946237 0.625448 0.60215054 0.60304659 0.59856631 0.59677419
0.59408602 0.61021505]
[ 0.58691756 0.6784946 0.64964158 0.66397849 0.67114695 0.66935484
0.67293907 0.66845878 0.65143369 0.640681 0.63530466 0.6344086
0.6281362 0.6281362 0.62634409 0.6281362 0.62903226 0.63799283
0.63709677 0.6978495]
[ 0.505018 0.53405018 0.59408602 0.65143369 0.66577061 0.66487455
0.65412186 0.64964158 0.64157706 0.63082437 0.62634409 0.6218638
0.62007168 0.6648746 0.62096774 0.62007168 0.62096774 0.62007168
0.62275986 0.81362 ]]
I tried to append as a list, using numpy's append, merge, and hstack. None of them worked. Any idea of how to get the previous output?
Use numpy.concatenate to join the arrays:
import numpy as np
a = np.array([[1, 2, 3, 4]])
b = np.array([[5, 6, 7, 8]])
arr = np.concatenate((a, b), axis=0)
print(arr)
# [[1 2 3 4]
# [5 6 7 8]]
Edit1: To do it inside the array (as mentioned in the comment) you can use numpy.vstack:
import numpy as np
for i in range(0, 3):
a = np.random.randint(0, 10, size=4)
if i == 0:
arr = a
else:
arr = np.vstack((arr, a))
print(arr)
# [[1 1 8 7]
# [2 4 9 1]
# [8 4 7 5]]
Edit2: Citing Iguananaut from the comments:
That said, using concatenate repeatedly can be costly. If you know the
size of the output in advance it's better to pre-allocate an array and
fill it as you go.
Let's assume I have 2 matrices which each of them represents vector:
X = np.matrix([[1],[2],[3]])
Y = np.matrix([[4],[5],[6]])
I want the output to be the result of multiplying it element by element, which means it should be:
[[4],[10],[18]]
Note that it is np.matrix and not np.array
Tested np.multiply() on ipython and it worked like a charm
In [41]: X = np.matrix([[1],[2],[3]])
In [42]: Y = np.matrix([[4],[5],[6]])
In [43]: np.multiply(X, Y)
Out[43]:
matrix([[ 4],
[10],
[18]])
so remember that NumPy matrix is a subclass of NumPy array, and array operations are element-wise.
therefore, you can convert your matrices to NumPy arrays, then multiply them with the "*" operator, which will be element-wise:
>>> import numpy as NP
>>> X = NP.matrix([[1],[2],[3]])
>>> Y = NP.matrix([[4],[5],[6]])
>>> X1 = NP.array(X)
>>> Y1 = NP.array(Y)
>>> XY1 = X1 * Y1
array([[ 4],
[10],
[18]])
>>> XY = matrix(XY1)
>>> XY
matrix([[ 4],
[10],
[18]])
alternatively you can use a generic function for element-wise multiplication:
>>> a = NP.matrix("4 5 7; 9 3 2; 3 9 1")
>>> b = NP.matrix("5 2 9; 8 4 2; 1 7 4")
>>> ab = NP.multiply(a, b)
>>> ab
matrix([[20, 10, 63],
[72, 12, 4],
[ 3, 63, 4]])
these two differ in the return type and so you probably want to choose the first if the next function in your data flow requires a NumPy array; if it requires a NumPy matrix, then the second
The two arrays:
a = numpy.array([[2,3,2],[5,6,1]])
b = numpy.array([3,5])
c = a * b
What I want is:
c = [[6,9,6],
[25,30,5]]
But, I am getting this error:
ValueError: operands could not be broadcast together with shapes (2,3) (2)
How to multiply a nD array with 1D array, where len(1D-array) == len(nD array)?
You need to convert array b to a (2, 1) shape array, use None or numpy.newaxis in the index tuple:
import numpy
a = numpy.array([[2,3,2],[5,6,1]])
b = numpy.array([3,5])
c = a * b[:, None]
Here is the document.
Another strategy is to reshape the
second array, so it has the same number of dimensions as the first array:
c = a * b.reshape((b.size, 1))
print(c)
# [[ 6 9 6]
# [25 30 5]]
Alternatively, the shape attribute of the second array can be modified in-place:
b.shape = (b.size, 1)
print(a.shape) # (2, 3)
print(b.shape) # (2, 1)
print(a * b)
# [[ 6 9 6]
# [25 30 5]]