I have an array of 2x2 complex matrices that represents a transformation of a scattering matrix over time. For my calculations I need a way to multiply such arrays between themselves (matrix multiplication); multiply each matrix in the array by another matrix; apply a transformation to all matrices in the array.
I've tried multiple ways of doing so with the numpy (4 column array, array of arrays, array of matrices, list of matrices), but each of them, while providing a nice interface for some of the required functions, makes the rest very awkward.
So here's the question - what is the best way to represent such structures and how would I carry out the required transformations over them?
examples
Initially data is in csv file:
import numpy as np
csv = np.arange(45.).reshape(5,9)
t = np.array(csv[:,0]) # time array
4 column array
transform csv to 4 column array:
data = np.apply_along_axis(lambda x: [x[1]+1j*x[2],
x[3]+1j*x[4],
x[5]+1j*x[6],
x[7]+1j*x[8]],1,csv)
array x matrix:
m = np.array([[1,0],[0,0]])
np.apply_along_axis(lambda x: (x.reshape(2,2).dot(m)).reshape(1,4),1,data)
array x array:
would probably require a for loop and array preallocation
transformation:
np.apply_along_axis(lambda x: [-(x[0]*x[3]-x[1]*x[2])/x[2],
x[0]/x[2],
-x[3]/x[2],
1/x[2]],1,data)
list of arrays
transform csv to list of arrays:
data = [np.array([[i[1]+1j*i[2],
i[3]+1j*i[4]],
[i[5]+1j*i[6],
i[7]+1j*i[8]]]) for i in csv]
array x matrix:
m = np.array([[1,0],[0,0]])
[i.dot(m) for i in data]
array x array:
[data[i].dot(data[i]) for i in range(len(data))]
transformation:
[np.array([[-(np.linalg.det(x))/x[0,1],
x[0,0]/x[1,0]],
[-x[1,1]/x[0,1],
1/x[0,1]]]) for x in data]
array of matrices
transform csv to array of matrices:
data = np.apply_along_axis(lambda x: [[x[1]+1j*x[2],
x[3]+1j*x[4]],
[x[5]+1j*x[6],
x[7]+1j*x[8]]],1,csv)
array x matrix:
m = np.array([[1,0],[0,0]])
data.dot(m)
array x array:
would probably require a for loop and array preallocation
data * data # not a dot product
transformation:
would probably require a for loop and array preallocation
Related
I have two arrays: 900x421 and 900x147. I need to correlate all columns from these arrays so that the output is 421x147. In Matlab function corr() does it, but I can't find a function that does the same in python.
the numpy.corrcoef function is the way to go. You need both arguments x and y to be of the same shape. You can do so by concatenate the two arrays. Let's say arr1 is of shape 900x421 and arr2 is of shape 900x147. You can do the following
import numpy as np
two_arrays = np.concatenate((arr1, arr2), axis=1) # 900x568
corr = np.corrcoef(two_arrays.T) # 568x568 array
desired_output = corr[0:421, 421:]
The np.corrcoef treats each row as a variable and each column as observation. That is why we need to transpose the array.
I have a problem in python where i would like to merge some sparse matrices into one. The sparse matrices are of csr_matrix type and have same amount of rows. When I use hstack to stack them together I obtain an array of matrices, but I would like to obtain a single matrix with the number of rows (which is the same for every matrix) and as the number of columns the sum of the columns number of every matrix.
Thanks for support.
You can do this using scipy.sparse.hstack. For example:
import numpy as np
from scipy import sparse
x = sparse.csr_matrix(np.random.randint(0, 2, size=(10, 10)))
y = sparse.csr_matrix(np.random.randint(0, 2, size=(10, 10)))
xy = sparse.hstack([x, y])
print(xy.shape)
# (10, 20)
print(type(xy))
# <class 'scipy.sparse.coo.coo_matrix'>
Given a numpy array and integer x, is there a way to create a multi-dimensional numpy array where each row is a slice of the original array starting from index 0 ... x without hard-coding? For example, if x = 3:
array = np.arange(10)
output = np.array([array, array[1:], array[2:], array[3:]])
I have a 3d matrix grid_z0, whose dimension are (let's say) 50x25x36. Each point of this matrix represents a cell. I would like to convert this matrix into a 1D array of size 50x25x36. I would also like to create 3 array of the same size showing the coordinate of the cell center.
The array cx,cy and cz stores the coordinate of the cell center in one direction.
This example work but it rather slow, especially for large data set. Is there a way to make it faster?
data={"x":[],"y":[],"z":[],"rho":[]}
for i in arange(0,50):
for j in arange(0,25):
for k in arange(0,36):
data["x"].append(cx[i])
data["y"].append(cy[j])
data["z"].append(cz[k])
data["f"].append(grid_z0[i][j][k])
You should consider using NumPy.
>>> import numpy as np
>>> a = np.random.rand(50,25,36) # Create a fake array
>>> print a.shape
(50, 25, 36)
>>> a.shape = -1 # Flatten the array in place
>>> print a.shape
(45000,)
When flattening your array, you're doing the equivalent of :
>>> b = []
>>> for i in range(a.shape[0]):
... for j in range(a.shape[1]):
... for k in range(a.shape[2]):
... b.append(a[i,j,k])
That is, the last axis is parsed first, then the second, then the first.
Given your three 1D lists cx, cy, cz of length N, you can construct a 2D array with:
>>> centers = np.array([cx,cy,cz])
>>> print centers.shape
(3, N)
Use Numpy for matrix/array manipulation.
# convert to 1D array :
grid_1d = np.asarray(grid_z0).ravel()
For the second question, you need a 3D meshgrid. See here for an exemple :
Numpy meshgrid in 3D
I have a 2d array and a 1d array and I need to multiply each element in the 1d array x each element in the 2d array columns. It's basically a matrix multiplication but numpy won't allow matrix multiplication because of the 1d array. This is because matrices are inherently 2d in numpy. How can I get around this problem? This is an example of what I want:
FrMtx = np.zeros(shape=(24,24)) #2d array
elem = np.zeros(24, dtype=float) #1d array
Result = np.zeros(shape=(24,24), dtype=float) #2d array to store results
some_loop to increment i:
some_other_loop to increment j:
Result[i][j] = (FrMtx[i][j] x elem[j])
Numerous efforts have given me errors such as arrays used as indices must be of integer or boolean type
Due to the NumPy broadcasting rules, a simple
Result = FrMtx * elem
Will give the desired result.
You should be able to just multiply your arrays together, but its not immediately obvious what 'direction' the arrays will be multiplied since the matrix is square. To be more explicit about which axes are being multiplied, I find it is helpful to always multiply arrays that have the same number of dimensions.
For example, to multiply the columns:
mtx = np.zeros(shape=(5,7))
col = np.zeros(shape=(5,))
result = mtx * col.reshape((5, 1))
By reshaping col to (5,1), we guarantee that axis 0 of mtx is multiplied against axis 0 of col. To multiply rows:
mtx = np.zeros(shape=(5,7))
row = np.zeros(shape=(7,))
result = mtx * row.reshape((1, 7))
This guarantees that axis 1 in mtx is multiplied by axis 0 in row.