Can I use a list to address a numpy array? - python

I'd like to assign a value to an element of a numpy array addressed by a list. Is this possible? It seems like the sort of thing you ought to be able to do.
I tried:
q = np.zeros((2,2,2))
index = [0,0,0]
print(index)
q[index]=4.3
print(q)
Which didn't give an error, which is promising, but q is now:
[[[ 4.3 4.3]
[ 4.3 4.3]]
[[ 0. 0. ]
[ 0. 0. ]]]
As opposed to:
[[[ 4.3 0. ]
[ 0. 0.]]
[[ 0. 0. ]
[ 0. 0. ]]]
As I hoped it would be.
Thanks in advance for your help.

You can't use a list to index a single element - it has to be a tuple:
import numpy as np
q = np.zeros((2,2,2))
index = [0,0,0]
print(index)
q[tuple(index)]=4.3
print(q)
[0, 0, 0]
[[[ 4.3 0. ]
[ 0. 0. ]]
[[ 0. 0. ]
[ 0. 0. ]]]

Related

the difference between `lower` and `upper` in LDLT decomposition

I have a problem in LDLT decomposition. Here is my code:
import numpy as np
from scipy.linalg import ldl
B = np.array([[2,-1,0], [-1,3,-1], [0,-1,4]]);
l0,d0, p = ldl(B, lower=0)
print('\nlower=0, L0= ')
print(l0)
print(d0)
l1,d1, p = ldl(B, lower=1)
print('\nlower=1, L1= ')
print(l1)
print(d1)
here is the output
lower=0, L0=
[[ 1. -0.36363636 0. ]
[ 0. 1. -0.25 ]
[ 0. 0. 1. ]]
[[1.63636364 0. 0. ]
[0. 2.75 0. ]
[0. 0. 4. ]]
lower=1, L1=
[[ 1. 0. 0. ]
[-0.5 1. 0. ]
[ 0. -0.4 1. ]]
[[2. 0. 0. ]
[0. 2.5 0. ]
[0. 0. 3.6]]
Well, the l1 and d1 equals the output of ldl() function in matlab.
and the l0 and d0 equals the output of gsl_linalg_ldlt_decomp() function in GSL.
But I want know the difference between the l0 and l1 matrixs.
and How to transform l0 d0 into l1 d1???
Thanks.

How to scatter a smaller array in to a larger array using a list as index?

I need help to obtain the following type of result in Python (that I was used to in Matlab):
M = numpy.zeros((5,5))
m = numpy.array([[1,2,3],[4,5,6],[7,8,9]])
indx = [0, 2, 3]
# in Matlab: M(indx,indx) = M(indx,indx) + m
so that the output is:
[[ 1. 0. 2. 3. 0.]
[ 0. 0. 0. 0. 0.]
[ 4. 0. 5. 6. 0.]
[ 7. 0. 8. 9. 0.]
[ 0. 0. 0. 0. 0.]]

Fast way to fill matrix from np.array of row index, column index, and max(values)

I have quite large arrays to fill matrix (about 5e6 elements). I know the fast way to fill is something like
(simplified example)
bbb = (np.array([1,2,3,4,1])) # row
ccc = (np.array([0,1,2,1,0])) # column
ddd = (np.array([55.5,22.2,33.3,44.4,11.1])) # values
experiment = np.zeros(shape=(5,3))
experiment[bbb, ccc] = [ddd] # filling
>[[ 0. 0. 0. ]
[ 11.1 0. 0. ]
[ 0. 22.2 0. ]
[ 0. 0. 33.3]
[ 0. 44.4 0. ]]
but if I want the max ddd instead. Something like at # filling
#pseudocode
experiment[bbb, ccc] = [ddd if ddd > experiment[bbb, ccc]]
The matrix should return
>[[ 0. 0. 0. ]
[ 55.5 0. 0. ]
[ 0. 22.2 0. ]
[ 0. 0. 33.3]
[ 0. 44.4 0. ]]
What is a good fast way to get max to fill the matrix from np.array here?
You can use np.ufunc.at on np.maximum.
np.ufunc.at performs the preceding ufunc "unbuffered and in-place". This means all indices appearing in [bbb, ccc] will be processed by np.maximum, no matter how ofthen those indices appear.
In your case (0, 1) appears twice, so it will be processed twice, each time picking the maximum of experiment[bbb, ccc] and ddd.
np.maximum.at(experiment, [bbb, ccc], ddd)
# array([[ 0. , 0. , 0. ],
# [ 55.5, 0. , 0. ],
# [ 0. , 22.2, 0. ],
# [ 0. , 0. , 33.3],
# [ 0. , 44.4, 0. ]])

Update 3 and 4 dimension elements of numpy array

I have a numpy array of shape [12, 8, 5, 5]. I want to modify the values of 3rd and 4th dimension for each element.
For e.g.
import numpy as np
x = np.zeros((12, 80, 5, 5))
print(x[0,0,:,:])
Output:
[[ 0. 0. 0. 0. 0.]
[ 0. 0. 0. 0. 0.]
[ 0. 0. 0. 0. 0.]
[ 0. 0. 0. 0. 0.]
[ 0. 0. 0. 0. 0.]]
Modify values:
y = np.ones((5,5))
x[0,0,:,:] = y
print(x[0,0,:,:])
Output:
[[ 1. 1. 1. 1. 1.]
[ 1. 1. 1. 1. 1.]
[ 1. 1. 1. 1. 1.]
[ 1. 1. 1. 1. 1.]
[ 1. 1. 1. 1. 1.]]
I can modify for all x[i,j,:,:] using two for loops. But, I was wondering if there is any pythonic way to do it without running two loops. Just curious to know :)
UPDATE
Actual use case:
dict_weights = copy.deepcopy(combined_weights)
for i in range(0, len(combined_weights[each_layer][:, 0, 0, 0])):
for j in range(0, len(combined_weights[each_layer][0, :, 0, 0])):
# Extract 5x5
trans_weight = combined_weights[each_layer][i,j]
trans_weight = np.fliplr(np.flipud(trans_weight ))
# Update
dict_weights[each_layer][i, j] = trans_weight
NOTE: The dimensions i, j of combined_weights can vary. There are around 200 elements in this list with varied i and j dimensions, but 3rd and 4th dimensions are always same (i.e. 5x5).
I just want to know if I can updated the elements combined_weights[:,:,5, 5] with transposed values without running 2 for loops.
Thanks.
Simply do -
dict_weights[each_layer] = combined_weights[each_layer][...,::-1,::-1]

Meshgrid a N-columned matrix in Numpy (or smth else)

Python version: 2.7
I have the following numpy 2d array:
array([[ -5.05000000e+01, -1.05000000e+01],
[ -4.04000000e+01, -8.40000000e+00],
[ -3.03000000e+01, -6.30000000e+00],
[ -2.02000000e+01, -4.20000000e+00],
[ -1.01000000e+01, -2.10000000e+00],
[ 7.10542736e-15, -1.77635684e-15],
[ 1.01000000e+01, 2.10000000e+00],
[ 2.02000000e+01, 4.20000000e+00],
[ 3.03000000e+01, 6.30000000e+00],
[ 4.04000000e+01, 8.40000000e+00]])
If I wanted to find all the combinations of the first and the second columns, I would use np.array(np.meshgrid(first_column, second_column)).T.reshape(-1,2). As a result, I would get a 100*1 matrix with 10*10 = 100 data points. However, my matrix can have 3, 4, or more columns, so I have a problem of using this numpy function.
Question: how can I make an automatically meshgridded matrix with 3+ columns?
UPD: for example, I have the initial array:
[[-50.5 -10.5]
[ 0. 0. ]]
As a result, I want to have the output array like this:
array([[-10.5, -50.5],
[-10.5, 0. ],
[ 0. , -50.5],
[ 0. , 0. ]])
or this:
array([[-50.5, -10.5],
[-50.5, 0. ],
[ 0. , -10.5],
[ 0. , 0. ]])
You could use * operator on the transposed array version that unpacks those columns sequentially. Finally, a swap axes operation is needed to merge the output grid arrays as one array.
Thus, one generic solution would be -
np.swapaxes(np.meshgrid(*arr.T),0,2)
Sample run -
In [44]: arr
Out[44]:
array([[-50.5, -10.5],
[ 0. , 0. ]])
In [45]: np.swapaxes(np.meshgrid(*arr.T),0,2)
Out[45]:
array([[[-50.5, -10.5],
[-50.5, 0. ]],
[[ 0. , -10.5],
[ 0. , 0. ]]])

Categories