I have two arrays:
order = np.array([ 0, 1, 2, 3, 4, 5, 6, 10, 7, 8, 9])
X = np.array([[1,1], [1,2], [2,1], [1,7], [7,3], [8,3], [8,2], [10,5], [10,6], [10,7], [10,1]]
And I'm running the foll)owing code:
m,n = X.shape
for i in range(m):
print( i," ",X[order[i]])
I get the following result:
0 [1 1]
1 [1 2]
2 [2 1]
3 [1 7]
4 [7 3]
5 [8 3]
6 [8 2]
7 [10 1]
8 [10 1]
9 [10 1]
10 [10 1]
Why are the last elements changed? I don't see why X is changed by indexing some elements.
edit: added np.array
import numpy
# your data (order and X)
m, n = numpy.shape(X)
for i in range(m):
print(i, " ", X[order[i]])
Output:
0 [1, 1]
1 [1, 2]
2 [2, 1]
3 [1, 7]
4 [7, 3]
5 [8, 3]
6 [8, 2]
7 [10, 1]
8 [10, 5]
9 [10, 6]
10 [10, 7]
Related
Simple 1D case
I would like to get a substring with wraparound.
str = "=Hello community of Python="
# ^^^^^ ^^^^^^^ I want this wrapped substring
str[-7]
> 'P'
str[5]
> 'o'
str[-7:5]
> ''
Why does this slice of a sequence starting at a negative index and ending in a positive one result in an empty string?
How would I get it to output "Python==Hell"?
Higher dimensional cases
In this simple case I could do some cutting and pasting, but in my actual application I want to get every sub-grid of size 2x2 of a bigger grid - with wraparound.
m = np.mat('''1 2 3;
4 5 6;
7 8 9''')
And I want to get all submatrices centered at some location (x, y), including '9 7; 3 1'. Indexing with m[x-1:y+1] doesn't work for (x,y)=(0,0), nor does (x,y)=(1,0) give 7 8; 1 2
3D example
m3d = np.array(list(range(27))).reshape((3,3,3))
>
array([[[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8]],
[[ 9, 10, 11],
[12, 13, 14],
[15, 16, 17]],
[[18, 19, 20],
[21, 22, 23],
[24, 25, 26]]])
m3d[-1:1,-1:1,-1:1]
# doesn't give [[[26, 24], [20, 18]], [8, 6], [2, 0]]]
If need be I could write some code which gets the various sub-matrices and glues them back together, but this approach might get quite cumbersome when I have to apply the same method to 3d arrays.
I was hoping there would be an easy solution. Maybe numpy can help out here?
Using Advanced indexing (see the section starting with "From a 4x3 array the corner elements should be selected using advanced indexing"):
import numpy as np
m = np.mat('''1 2 3;
4 5 6;
7 8 9''')
print(m[np.ix_(range(-1, 1), range(-1, 1))])
print(m[np.ix_(range(-2, 2), range(-2, 2))])
print(m[np.arange(-2, 2)[:, np.newaxis], range(-2, 2)])
Output (Attempt This Online!):
[[9 7]
[3 1]]
[[5 6 4 5]
[8 9 7 8]
[2 3 1 2]
[5 6 4 5]]
[[5 6 4 5]
[8 9 7 8]
[2 3 1 2]
[5 6 4 5]]
Going through all sub-matrices
Since you want to go through all sub-matrices, we can beforehand separately prepare the row ranges and the column ranges, and then use pairs of them to quickly index:
import numpy as np
A = np.mat('''1 2 3;
4 5 6;
7 8 9''')
m, n = A.shape
rowranges = [
(np.arange(i, i+2) % m)[:, np.newaxis]
for i in range(m)
]
colranges = [
np.arange(j, j+2) % n
for j in range(n)
]
for rowrange in rowranges:
for colrange in colranges:
print(A[rowrange, colrange])
Output (Attempt This Online!):
[[1 2]
[4 5]]
[[2 3]
[5 6]]
[[3 1]
[6 4]]
[[4 5]
[7 8]]
[[5 6]
[8 9]]
[[6 4]
[9 7]]
[[7 8]
[1 2]]
[[8 9]
[2 3]]
[[9 7]
[3 1]]
3D case
m3d = np.array(list(range(27))).reshape((3,3,3))
m3d[np.ix_(range(-1,1), range(-1,1), range(-1,1))]
Output:
array([[[26, 24],
[20, 18]],
[[ 8, 6],
[ 2, 0]]])
Simply combine the two halfs yourself:
>>> str[-7:]+str[:5]
'Python==Hell'
You could repeat your data enough so that you don't need wraparound.
Substrings of length 3:
s = 'Python'
r = 3
s2 = s + s[:r-1]
for i in range(len(s)):
print(s2[i:i+r])
Output:
Pyt
yth
tho
hon
onP
nPy
Sub-matrices of size 2×2:
import numpy as np
m = np.mat('''1 2 3;
4 5 6;
7 8 9''')
r = 2
m2 = np.tile(m, (2, 2))
for i in range(3):
for j in range(3):
print(m2[i:i+r, j:j+r])
Output (Attempt This Online!):
[[1 2]
[4 5]]
[[2 3]
[5 6]]
[[3 1]
[6 4]]
[[4 5]
[7 8]]
[[5 6]
[8 9]]
[[6 4]
[9 7]]
[[7 8]
[1 2]]
[[8 9]
[2 3]]
[[9 7]
[3 1]]
For larger more-dimensional arrays, the simple np.tile adds mmore than necessary. You really just need to increase the size by + r-1 in each dimension, not by * 2. Like I did with the string. Not sure how to do that well with arrays. Plus I think you can also make your negative indexes work, so we just need someone to come along and do that.
I would like to know if there was a way to generate a matrix with values based from a larger matrix. For example, if I have
larger_matrix = np.random.randint(10, size=(10,5))
Out[1]:
array([[0, 9, 0, 0, 3],
[9, 4, 7, 7, 0],
[9, 4, 5, 6, 9],
[6, 3, 1, 7, 3],
[8, 4, 6, 9, 7],
[8, 1, 5, 8, 8],
[9, 9, 6, 0, 9],
[9, 9, 6, 8, 7],
[5, 5, 6, 6, 4],
[4, 4, 7, 0, 7]])
and I want to create smaller_matrix of size (4, 5), with values randomly sampled from larger_matrix, how should I go about this? I'm aware that the function np.random.choice() exists, but I'm quite unsure if it would be helpful for my problem because I'm dealing with matrices instead of lists. Thank you.
Use flatten to convert 2d larger_matrix to 1d.
Then you can use random.choice to get random sample from larger_matrix
Finally, use reshape to convert 1d list to 2d matrix
code:
import numpy as np
larger_matrix = np.random.randint(10, size=(10,5))
print(larger_matrix)
n = 4
m = 5
print(np.reshape(np.random.choice(larger_matrix.flatten(),size = n*m),(n,m)))
result:
[[7 4 4 6 0]
[5 7 0 6 8]
[9 9 0 0 5]
[9 8 0 6 7]
[0 9 8 8 1]
[3 7 1 0 0]
[8 9 2 3 8]
[6 3 7 2 9]
[9 7 5 9 3]
[8 8 3 5 8]]
[[0 0 8 0 9]
[6 9 2 7 0]
[8 7 6 0 7]
[7 4 9 3 7]]
You can run a for loop inside a for loop and use it to fill the smaller matrix with random indexes from the matrix.
For i in range(len(larger_matrix)): For j in range(len(larger_matrix[0])): smaller_matrix[i][j] = larger_matrix[rand1][rand2]
That should cover it. Just make sure you generate 2 new numbers each time.
You could do it like this but bear in mind that the choices taken from the large array may be duplicated:-
import numpy as np
import random
R1 = 10
R2 = 4
C = 5
m = np.random.randint(R1, size=(R1, C))
print(m)
print()
n = []
for _ in range(R2):
n.append(random.choice(m))
print(np.array(n))
In a single line, how can I get the product of the arrays of an array?
I need it to be done for multi columns cases
2 columns example:
X = [[1 4]
[2 3]
[0 2]
[1 5]
[3 1]
[3 6]]
sol = [4 6 0 5 3 18]
4 columns example:
X = [[1 4 2 3]
[2 3 1 5]
[0 2 3 4]
[1 5 2 2]
[3 1 1 6]
[3 6 3 1]]
sol = [24 30 0 20 18 54]
This is a row-wise multiplication. You can perform this with:
X.prod(axis=1)
for example:
>>> X
array([[1, 4],
[2, 3],
[0, 2],
[1, 5],
[3, 1],
[3, 6]])
>>> a.prod(axis=1)
array([ 4, 6, 0, 5, 3, 18])
You can also use numpy.multiply.reduce
np.multiply.reduce(x, axis=1)
I am trying to do something that should be straightforward and can be accomplished in a for-loop but I am trying to avoid that.
I would like to get the index of the minimum value in each slice along a certain axis of a numpy.ndarray, a. I am more interested in the index than the value itself. I use the index to get a value from another 2D array with shape equal to the first 2 dimensions of a.
Here is a naive implementation using a for-loop:
a = np.random.randint(0, 10, 60).reshape(3, 4, 5)
print(a)
for i in range(a.shape[-1]):
idx = a[..., i].argmin()
print('Slice:', i, '| Index:', idx, '| min value:',
a[..., i].flat[idx])
Out:
[[[1 9 4 0 7]
[6 3 1 6 8]
[7 8 2 0 2]
[8 6 1 6 5]]
[[8 7 0 6 9]
[7 2 6 4 5]
[3 4 9 2 9]
[1 4 8 0 7]]
[[1 4 6 6 2]
[9 9 5 6 7]
[6 2 8 9 9]
[3 9 8 5 4]]]
Slice: 0 | Index: 0 | min value: 1
Slice: 1 | Index: 5 | min value: 2
Slice: 2 | Index: 4 | min value: 0
Slice: 3 | Index: 0 | min value: 0
Slice: 4 | Index: 2 | min value: 2
I realise I can pass an axis keyword argument to argmin but that does not produce the result I am looking for.
For the specific case given in your question, you can reshape your array, then use argmin:
>>> import numpy as np
>>> a = np.array([[[1, 9, 4, 0, 7],
... [6, 3, 1, 6, 8],
... [7, 8, 2, 0, 2],
... [8, 6, 1, 6, 5]],
...
... [[8, 7, 0, 6, 9],
... [7, 2, 6, 4, 5],
... [3, 4, 9, 2, 9],
... [1, 4, 8, 0, 7]],
...
... [[1, 4, 6, 6, 2],
... [9, 9, 5, 6, 7],
... [6, 2, 8, 9, 9],
... [3, 9, 8, 5, 4]]])
>>> a.reshape(-1, a.shape[2]).min(axis=0)
array([1, 2, 0, 0, 2])
>>> a.reshape(-1, a.shape[2]).argmin(axis=0)
array([0, 5, 4, 0, 2])
>>>
The shape[2] comes from the fact that this is the dimension (in this case, the inner dimension, or rows), where you don't want to calculate the minimum across: you're calculating the minimum across the first two dimensions.
You also need the slice number: basically just the second index of your elements. That is easy, since that one is sequential, and is just:
slices = np.arange(a.shape[2])
I have for example
A = [[1 2 3 4 5]
[2 4 5 8 7]
[9 8 4 5 2]
[1 2 4 7 2]
[5 9 8 7 6]
[1 2 5 4 3]]
So the shape of A = (5,6)
What I want is now the max of each column and return the result as eg:
A = [[9 9 8 8 7]] with as shape (5,1)
And at the same time I would like to receive the index of the max value from each column.
Is this possible? I don't find immediatly the sollution within the np.array basic doc.
You could use ndarray.max().
The axis keyword argument describes what axis you want to find the maximum along.
keepdims=True lets you keep the input's dimensions.
To get the indizes of the maxima in the columns, you can use the ndarray.argmax() function.
You can also pass the axis argument ot this function, but there is no keepdims option.
In both commands axis=0 describes the columns, axis=1 describes the rows.
The standard value axis=None would search the maximum in the entire flattened array.
Example:
import numpy as np
A = np.asarray(
[[1, 2, 3, 4, 5],
[2, 4, 5, 8, 7],
[9, 8, 4, 5, 2],
[1, 2, 4, 7, 2],
[5, 9, 8, 7, 6],
[1, 2, 5, 4, 3]])
print(A)
max = A.max(axis=0, keepdims=True)
max_index = A.argmax(axis=0)
print('Max:', max)
print('Max Index:', max_index)
This prints:
[[1 2 3 4 5]
[2 4 5 8 7]
[9 8 4 5 2]
[1 2 4 7 2]
[5 9 8 7 6]
[1 2 5 4 3]]
Max: [[9 9 8 8 7]]
Max Index: [2 4 4 1 1]
you can use numpy as well.
Example:
import numpy as np
A = [[1, 2, 3, 4, 5],
[2, 4, 5, 8, 7],
[9, 8, 4, 5, 2],
[1, 2, 4, 7, 2],
[5, 9, 8, 7, 6],
[1, 2, 5, 4, 3]]
print(A)
A=np.array(A)
print(A.max(axis=0))