I have two matrices, m0.shape = [10, 3, 3] and m1.shape = [10, 3]. What I want to do would done this way using loops:
m0 = np.zeros((10, 3, 3))
m1 = np.zeros((10, 3))
a = np.zeros((10, 3))
for i in range(10):
a += m1 # m0[i]
The question is: Can I somehow achieve the same result by using builtin numpy operations?
I think you have two options:
import numpy as np
np.sum(m1 # m0, axis=0)
or using numpy.einsum
np.einsum('ij,kjl->il', m1, m0)
Related
I have 2 arrays as input. On array as output. Array a holds the data and is of shape (N,M), while array b holds the indices and is of shape (N,X,2). The resulting array should be of shape (N,X), with the values taken from a.
Right now it only works with a for loop. How could I vectorize it since I have huge arrays as input?
Below is a sample code to demonstrate what I have right now:
import numpy as np
# a of shape (N,M)
# b of shape (N,X,2)
# t_result of shape (N, X)
a = np.random.randint(0, 10, size=(10, 10))
b = np.random.randint(0, 2, size=(10, 9, 2))
t_result = np.empty((10, 9))
for i in range(b.shape[0]):
t_result[i] = a[i, b[i, :, 0]]
print(t_result)
print(t_result.shape)
Ok so I adapted a bit the answer to another post from scleronomic:
import numpy as np
# a of shape (N,M)
# b of shape (N,X,2)
# t_result of shape (N, X)
a = np.random.randint(0, 10, size=(10, 10))
b = np.random.randint(0, 2, size=(10, 9, 2))
t_result = np.empty((10, 9))
t_result = a[np.arange(a.shape[0])[:,None],b[np.arange(b.shape[0]),:,0]]
print(t_result)
print(t_result.shape)
I am not sure whether or not it is the best solution but it works.
import numpy as np
import scipy.sparse
x = np.random.randint(0, 1000, (1000, 100))
# prob better way to do this
d = np.random.random((1000,1000))
d[d < 0.99] = 0
y = scipy.sparse.csr_matrix(d)
What I would like to do is to create a new matrix z containing the values of y at the indices in x.
ie [0, 0] of z should contain the y[0, x[0, 0]]
[0, 1] of z should contain the y[0, x[0, 1]]
%time for i in range(1000): x[i, y[i]].todense()
~247ms
%time for i in range(1000): np.take(x[i].todense(), y[i])
~150ms
both of the above work, but I am looking for a faster method- this is currently the bottleneck on my code.
Please assume that representing the whole scipy.sparse matrix as dense isn't feasible.
edit:
%time z = np.vstack([q.todense()[0, p] for q, p in zip(x, y)])
is ~110ms
The answer seems to be to use an appropriately shaped broadcasting index, as outlined here: How to generate multi-dimensional 2D numpy index using a sub-index for one dimension
(answer deserves more upvotes)!
%time res = y[np.arange(0, 1000).reshape((-1, 1)), x].todense()
Say I have a numpy array [[1,2],[3,4],[5,6]], how do I do element-wise mathematics such that I could iterate over each XY pair to get X^2 + Y^2 for each pair?
Since you tagged numpy:
(np.array(a)**2).sum(-1)
Output:
array([ 5, 25, 61])
import numpy as np
arr1 = np.array([[1,2],[3,4],[5,6]])
rows = arr1.shape[0]
cols = arr1.shape[1]
ans = []
for x in range(rows):
answer = arr1[x,0]**2 + arr1[x,1]**2
ans.append(answer)
print(ans)
This question already has answers here:
How to copy a 2D array into a 3rd dimension, N times?
(7 answers)
Closed 3 years ago.
Given a 2x2 matrix r = np.array([[1, 0], [0, 0]], dtype=complex), how do I create a block matrix such that I get N r as its entries so that I get
np.array([r, r,..., r, r])
Is there like a np.something(r, 5) so that it gives np.array([r, r, r, r, r])?
You can use np.array again to get what you want.
One way of doing this is as follows:
import numpy as np
r = np.array([[1, 0], [0, 0]], dtype=complex)
samples = 5
a = np.array([r]*samples)
print(a.shape) # (samples, 2, 2) = (5, 2, 2)
print(a[0]) # array([[1.+0.j, 0.+0.j], [0.+0.j, 0.+0.j]])
To scale or speed it up, you may want to use the following:
import numpy as np
n_samples = 10000
b = np.repeat(a[np.newaxis, :, :], n_samples, axis=0)
I have a numpy array my_array of size 100x20. I want to create a function that receives as an input a 2d numpy array my_arr and an index x and will return two arrays one with size 1x20 test_arr and one with 99x20 train_arr. The vector test_arr will correspond to the row of the matrix my_arr with the index x and the train_arr will contain the rest rows. I tried to follow a solution using masking:
def split_train_test(my_arr, x):
a = np.ma.array(my_arr, mask=False)
a.mask[x, :] = True
a = np.array(a.compressed())
return a
Apparently this is not working as i wanted. How can i return a numpy array as a result and the train and test arrays properly?
You can use simple index and numpy.delete for this:
def split_train_test(my_arr, x):
return np.delete(my_arr, x, 0), my_arr[x:x+1]
my_arr = np.arange(10).reshape(5,2)
train, test = split_train_test(my_arr, 2)
train
#array([[0, 1],
# [2, 3],
# [6, 7],
# [8, 9]])
test
#array([[4, 5]])
You can also use a boolean index as the mask:
def split_train_test(my_arr, x):
# define mask
mask=np.zeros(my_arr.shape[0], dtype=bool)
mask[x] = True # True only at index x, False elsewhere
return my_arr[mask, :], my_arr[~mask, :]
Sample run:
test_arr, train_arr = split_train_test(np.random.rand(100, 20), x=10)
print(test_arr.shape, train_arr.shape)
((1L, 20L), (99L, 20L))
EDIT:
If someone is looking for the general case where more than one element needs to be allocated to the test array (say 80%-20% split), x can also accept an array:
my_arr = np.random.rand(100, 20)
x = np.random.choice(np.arange(my_arr.shape[0]), int(my_arr .shape[0]*0.8), replace=False)
test_arr, train_arr = split_train_test(my_arr, x)
print(test_arr.shape, train_arr.shape)
((80L, 20L), (20L, 20L))