x = np.array([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15])
我想从5的每个块中获取前2行数组x,结果应为:
x[fancy_indexing] = [1,2, 6,7, 11,12]
使用for循环构建索引很容易。
是否有单线切片技巧可以将其拉下来?这里简单点。
答案 0 :(得分:3)
方法#1 这是使用boolean-indexing
的矢量化单行 -
x[np.mod(np.arange(x.size),M)<N]
方法#2 如果你想要表现,这是使用NumPy strides
的另一种矢量化方法 -
n = x.strides[0]
shp = (x.size//M,N)
out = np.lib.stride_tricks.as_strided(x, shape=shp, strides=(M*n,n)).ravel()
示例运行 -
In [61]: # Inputs
...: x = np.array([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15])
...: N = 2
...: M = 5
...:
In [62]: # Approach 1
...: x[np.mod(np.arange(x.size),M)<N]
Out[62]: array([ 1, 2, 6, 7, 11, 12])
In [63]: # Approach 2
...: n = x.strides[0]
...: shp = (x.size//M,N)
...: out=np.lib.stride_tricks.as_strided(x,shape=shp,strides=(M*n,n)).ravel()
...:
In [64]: out
Out[64]: array([ 1, 2, 6, 7, 11, 12])
答案 1 :(得分:1)
将数组重塑为多行五列,然后取(切片)每行的前两列。
>>> x
array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])
>>> x.reshape(x.shape[0] / 5, 5)[:,:2]
array([[ 1, 2],
[ 6, 7],
[11, 12]])
或者
>>> x.reshape(x.shape[0] / 5, 5)[:,:2].flatten()
array([ 1, 2, 6, 7, 11, 12])
>>>
它仅适用于长度为5的倍数的1-d数组。
答案 2 :(得分:0)
import numpy as np
x = np.array(range(1, 16))
y = np.vstack([x[0::5], x[1::5]]).T.ravel()
y
// => array([ 1, 2, 6, 7, 11, 12])
获取数组N
中每个M
行的第[1, 2, ..., K
行:
import numpy as np
K = 30
M = 5
N = 2
x = np.array(range(1, K+1))
y = np.vstack([x[i::M] for i in range(N)]).T.ravel()
y
// => array([ 1, 2, 6, 7, 11, 12, 16, 17, 21, 22, 26, 27])
请注意.T
和.ravel()
是快速操作:它们不会复制任何数据,只是操纵数组的尺寸和步幅。
如果您坚持使用花式索引获取切片:
import numpy as np
K = 30
M = 5
N = 2
x = np.array(range(1, K+1))
fancy_indexing = [i*M+n for i in range(len(x)//M) for n in range(N)]
x[fancy_indexing]
// => array([ 1, 2, 6, 7, 11, 12, 16, 17, 21, 22, 26, 27])
答案 3 :(得分:0)
我首先想到你需要这个才能用于2d阵列,因为你的“M行的每个块的前N行”都是这样的,所以我会把这个解决方案保留下去。
你可以通过将数组重塑为3d来实现一些魔力:
// ===== Code from file PersonInfo.java =====
public class PersonInfo {
private int numKids;
public void setNumKids(int personsKids) {
numKids = personsKids;
return;
}
public void incNumKids() {
numKids = numKids + 1;
return;
}
public int getNumKids() {
return numKids;
}
}
// ===== end =====
// ===== Code from file CallPersonInfo.java =====
public class CallPersonInfo {
public static void main (String [] args) {
PersonInfo person1 = new PersonInfo();
person1.setNumKids(3);
//changes must be made after this line. So NO changes above this line.
System.out.println("Kids: " + person1.getNumKids());
person1.setNumKids(4);
System.out.println("New baby, kids now: " + person1.getNumKids());
//changes must be made above this line. So NO changes below this line.
return;
}
}
// ===== end =====
这将根据您的偏好提取每列。为了将它用于你的1d案例,你需要使用M = 5 # size of blocks
N = 2 # number of columns to cut
x = np.arange(3*4*M).reshape(4,-1) # (4,3*N)-shaped dummy input
x = x.reshape(x.shape[0],-1,M)[:,:,:N+1].reshape(x.shape[0],-1) # (4,3*N)-shaped output
将你的1d阵列变成2d阵列。