slice matrix by different index arrary - python

I have a, ex 5*3 array such as
[1,2,3]
[4,5,6]
[7,8,9]
[10,11,12]
[13,14,15]
and I have 3 list to select them, ex
a1 = [0,1,2]
a2 = [0,1,3]
a3 = [0,2,4]
Now I want to get 3 array, each comes from a for a1, a2 & a3
also, a1 selects 1st column only, a2 selects 2nd column only...
for given example, I want
[1,4,7], [2,5,11], [9,12,15]
What's the best way to do it?
Thanks.

In [913]: arr = np.arange(1,16).reshape(5,3)
In [914]: arr
Out[914]:
array([[ 1, 2, 3],
[ 4, 5, 6],
[ 7, 8, 9],
[10, 11, 12],
[13, 14, 15]])
In [915]: idx = np.array([[0,1,2],[0,1,3],[0,2,4]])
In [916]: idx.shape
Out[916]: (3, 3)
We want to select a (3,3) array of values, where idx identifies rows. So we need an column index that broadcasts with it. [0,1,2] will do.
In [917]: arr[idx, np.arange(3)]
Out[917]:
array([[ 1, 5, 9],
[ 1, 5, 12],
[ 1, 8, 15]])
Oops, wrong selection; let's try the transpose:
In [918]: arr[idx.T, np.arange(3)]
Out[918]:
array([[ 1, 2, 3],
[ 4, 5, 9],
[ 7, 11, 15]])

Related

transfer 3D NumPy array into a 2D NumPy array

let's say a NumPy array
a = np.array(
[[[1,2,3],
[4,5,6]],
[[7,8,9],
[10,11,12]]])
the shape will be like (2,2,3).
I'd like to make it look like this:
a = np.array(
[[1,2,3],
[7,8,9],
[4,5,6],
[10,11,12]]
)
which shape will be like (4,3).
if I use reshape, it will look like as:
a = np.array(
[[1,2,3],
[4,5,6],
[7,8,9],
[10,11,12]]
)
Which is NOT what I want. How to do this?
One way using numpy.stack and vstack:
np.vstack(np.stack(a, 1))
Output:
array([[ 1, 2, 3],
[ 7, 8, 9],
[ 4, 5, 6],
[10, 11, 12]])
By using indexing method, an idx list could be created that specifies which indices of the ex a must be placed as which indices in the new one i.e. idx is a rearranging list:
idx = [0, 2, 1, 3]
a = a.reshape(4, 3)[idx]
a is firstly reshaped to the intended shape, which is (4,3), and then rearranged by the idx. idx[1] = 2 is showing that value in index = 2 of the ex a will be replaced to index = 1 in the new a.
Here is a more pythonic version of your problem.
This uses concatenate so append the rows of your array.
a = np.array(
[[[1,2,3],
[4,5,6]],
[[7,8,9],
[10,11,12]]]
)
def transform_2d(a_arr):
nrow = len(a[:])
all = a_arr[:,0]
for i in range(1,nrow):
all = np.concatenate((all, a_arr[:,i] ))
return all
print(transform_2d(a))
First use transpose (or swapaxes) to bring the desire rows together:
In [268]: a.transpose(1,0,2)
Out[268]:
array([[[ 1, 2, 3],
[ 7, 8, 9]],
[[ 4, 5, 6],
[10, 11, 12]]])
then the reshape follows:
In [269]: a.transpose(1,0,2).reshape(-1,3)
Out[269]:
array([[ 1, 2, 3],
[ 7, 8, 9],
[ 4, 5, 6],
[10, 11, 12]])

How can I merge rows in np matrix?

I've got a numpy matrix that has 2 rows and N columns, e.g. (if N=4):
[[ 1 3 5 7]
[ 2 4 6 8]]
The goal is create a string 1,2,3,4,5,6,7,8.
Merge the rows such that the elements from the first row have the even (1, 3, ..., N - 1) positions (the index starts from 1) and the elements from the second row have the odd positions (2, 4, ..., N).
The following code works but it isn't really nice:
xs = []
for i in range(number_of_cols):
xs.append(nums.item(0, i))
ys = []
for i in range(number_of_cols):
ys.append(nums.item(1, i))
nums_str = ""
for i in range(number_of_cols):
nums_str += '{},{},'.format(xs[i], ys[i])
Join the result list with a comma as a delimiter (row.join(','))
How can I merge the rows using built in functions (or just in a more elegant way overall)?
Specify F order when flattening (or ravel):
In [279]: arr = np.array([[1,3,5,7],[2,4,6,8]])
In [280]: arr
Out[280]:
array([[1, 3, 5, 7],
[2, 4, 6, 8]])
In [281]: arr.ravel(order='F')
Out[281]: array([1, 2, 3, 4, 5, 6, 7, 8])
Joining rows can be done this way :
>>> a = np.arange(12).reshape(3,4)
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
>>> np.hstack([a[i,:] for i in range(a.shape[0])])
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
Then it's simple to convert this array into string.
Here's one way of doing it:
out_str = ','.join(nums.T.ravel().astype('str'))
We are first transposing the array with .T, then flattening it with .ravel(), then converting each element from int to str, and then applying `','.join() to combine all the str elements
Trying it out:
import numpy as np
nums = np.array([[1,3,5,7],[2,4,6,8]])
out_str = ','.join(nums.T.ravel().astype('str'))
print (out_str)
Result:
1,2,3,4,5,6,7,8

How to select row or column from a matrix?

Here I have a matrix a=np.array([[1,2,3,4,5],[6,7,8,9,10],[11,12,13,14,15]])
I want to select all rows, but the column I want to select is from the first to the third one.
It should be [[1,2,3],[6,7,8],[11,12,13]]
However, I have ever tried a[:,[0,2]], but it shows
array([[ 1, 3],
[ 6, 8],
[11, 13]])
It seems not the correct, so I tried another one a[:][0:2], it still is a wrong result.
So I want to ask if there are any function or method can fix the problem?
Sounds like you are looking for a[:, 0:3]:
In [4]: a[:, 0:3]
Out[4]:
array([[ 1, 2, 3],
[ 6, 7, 8],
[11, 12, 13]])
I think need indexing 0:3:
print (a[:,0:3])
[[ 1 2 3]
[ 6 7 8]
[11 12 13]]
Try the following
a=np.array([[1,2,3,4,5],[6,7,8,9,10],[11,12,13,14,15]])
a = a[:,0:3]
print(a)
#Output
#array([[ 1, 2, 3],
# [ 6, 7, 8],
# [11, 12, 13]])

how can I do 2d 3d multiplication

I have two array one is 3d :
np.array([[[1,2,3],[3,2,1]],
[[2,3,2],[1,2,5]]])
and one 2d array :
np.array([[2,3],
[3,4]])
and I want to multiply these two to get
np.array([[[2,4,6],[9,6,3]],
[[6,9,6],[4,8,20]]])
How can I do this using numpy package? Thanks.
Use broadcasting:
In [129]: b[:,:,None] * a
Out[129]:
array([[[ 2, 4, 6],
[ 9, 6, 3]],
[[ 6, 9, 6],
[ 4, 8, 20]]])
With following names:
main = np.array([[[1,2,3],[3,2,1]],
[[2,3,2],[1,2,5]]])
fac = np.array([[2,3],
[3,4]])
It can managed with iteration as follows:
a1 = []
for i in [0,1]:
a2 = []
for j in [0,1]:
a2.append(main[i][j]*fac[i][j])
a1.append(a2)
print(a1)
Output:
[[array([2, 4, 6]), array([9, 6, 3])], [array([6, 9, 6]), array([ 4, 8, 20])]]

Sum nth columns elementwise in Numpy matrix

I have the following numpy matrix:
A = [[a,b,c,d,e,f],
[g,h,i,j,k,l],
...]
I need to sum all the nth columns in a element-wise fashion. So, if n is 2, the answer needs to be:
B = [[a+c+e, b+d+f],
[g+i+k, h+j+l],
...]
(like breaking the matrix into 3, each with 2 columns and adding them.)
But if n is 3, the answer needs to be:
C = [[a+d, b+e, c+f],
[g+j, h+k, i+l],
...]
(like breaking the matrix into 2, each with 3 columns and adding them.)
Is there a general case that will accept the value n without resorting to looping?
Reshape to split the last axis into two with the latter of length n and sum along the former -
A.reshape(A.shape[0],-1,n).sum(1)
Sample run -
In [38]: A
Out[38]:
array([[0, 5, 3, 2, 5, 6],
[6, 1, 0, 8, 4, 0],
[8, 6, 1, 5, 7, 0]])
In [39]: n = 2
In [40]: A.reshape(A.shape[0],-1,n).sum(1)
Out[40]:
array([[ 8, 13],
[10, 9],
[16, 11]])
In [41]: n = 3
In [42]: A.reshape(A.shape[0],-1,n).sum(1)
Out[42]:
array([[ 2, 10, 9],
[14, 5, 0],
[13, 13, 1]])

Categories