我有一个二维数组
test = np.arange(25).reshape((5, 5))
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]])
我需要一个像选择器一样的“检查板”。基本上,我想在第一行中选择奇数元素,甚至在第二行中选择元素,在第三行中选择奇数元素等。
在这种情况下(因为行号是奇数)我可以通过
得到它test.flatten()[::2]
Out[22]: array([ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24])
这两个维度中都是“每隔一个元素”。但是,如果我们尝试
test2 = np.arange(16).reshape((4, 4))
test2
Out[23]:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]])
test2.flatten()[::2]
Out[27]: array([ 0, 2, 4, 6, 8, 10, 12, 14])
不出所料,它没有成功。
无论(2d)矩阵的形状如何,生成我想要的选择类型的一般方法是什么?是否可以轻松(甚至可能)扩展到3d矩阵?
我更喜欢有效(矢量化或基于cython)的方法。
奖金: 3D :
test3 = np.arange(25*3).reshape((3, 5, 5))
Out[30]:
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, 27, 28, 29],
[30, 31, 32, 33, 34],
[35, 36, 37, 38, 39],
[40, 41, 42, 43, 44],
[45, 46, 47, 48, 49]],
[[50, 51, 52, 53, 54],
[55, 56, 57, 58, 59],
[60, 61, 62, 63, 64],
[65, 66, 67, 68, 69],
[70, 71, 72, 73, 74]]])
这里不是关于奇数甚至行,而是关于相邻元素。 没有两个相邻元素应该具有相同的颜色(属于同一个bool选择器)。
也就是说,如果我们选择test3[0, ...].flatten()[::2]
,我们会得到[0, ... 24]
。第一维中0
的邻近元素是25
,因此我们不希望这样。预期的输出是
np.hstack((test3[0, ...].flatten()[::2], test3[1, ...].flatten()[1::2], test3[2, ...].flatten()[::2], ))
Out[42]:
array([ 0, 2, 4, 6, 8, 10, 12, 14, 17, 19, 21, 23, 25, 27, 29, 31, 32,
34, 36, 38, 40, 42, 44, 46])
答案 0 :(得分:1)
这是一个矢量化解决方案 -
def checker_select(a):
m,n = a.shape[-2:]
i,j = np.ogrid[:m,:n]
mask = (i+j)%2==0
return a.reshape(-1,m,n)[:,mask].ravel()
array-initialization
-
def checker_select_v2(a):
m,n = a.shape[-2:]
mask = np.zeros((m,n), dtype=bool)
mask[::2,::2] = 1
mask[1::2,1::2] = 1
return a.reshape(-1,m,n)[:,mask].ravel()
2D
-
In [117]: a
Out[117]:
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]])
In [118]: checker_select(a)
Out[118]: array([ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24])
3D
-
In [144]: a
Out[144]:
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, 27, 28, 29],
[ 30, 31, 32, 33, 34],
[ 35, 36, 37, 38, 39],
[ 40, 41, 42, 43, 44],
[ 45, 46, 47, 48, 49]],
....
In [145]: checker_select(a)
Out[145]:
array([ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24,
25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49,
....
答案 1 :(得分:0)
你可以在普通的旧python
中做到这一点mat = np.arange(16).reshape((4, 4))
result = []
for row in range(len(mat)):
for col in range(len(mat[row])):
if row % 2 == 0 and col % 2 == 0:
result.append(mat[row][col])
elif row % 2 == 1 and col % 2 == 1:
result.append(mat[row][col])
print(result)
[0, 2, 5, 7, 8, 10, 13, 15]
如果你正在寻找一种更加pythonic的方式。
n = 6
m = 4
mat = np.arange(n * m).reshape((n, m))
flat = mat.flatten()
result = [flat[i] for i in range(len(flat)) if i // m % 2 == i % m % 2]
print(result)
[0, 2, 5, 7, 8, 10, 13, 15, 16, 18, 21, 23]
答案 2 :(得分:0)
使用基本列表和普通python的示例。
void Rev()
{
char ch;
cin.get(ch);
if (ch != '\n')
{
Rev();
cout.put(ch);
}