仅广播到特定值(numpy)

时间:2018-03-12 00:52:53

标签: python numpy

假设我有一个像这样的numpy数组:

array([[  0,  0,  1,  1,  0,  0 ],
       [  0,  1,  1,  1,  1,  0 ],
       [  1,  1,  1,  1,  1,  1 ],
       [  1,  1,  1,  1,  1,  1 ],
       [  0,  1,  1,  1,  1,  0 ],
       [  0,  0,  1,  1,  0,  0 ]])

有没有办法将另一个数组广播到这个数组只有特定的值,例如值为1的单元格

例如,如果我想将以下数组广播到上面的数组,

array([10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33])

然后我希望得到以下输出:

array([[  0,  0, 10, 11,  0,  0 ],
       [  0, 12, 13, 14, 15,  0 ],
       [ 16, 17, 18, 19, 20, 21 ],
       [ 22, 23, 24, 25, 26, 27 ],
       [  0, 28, 29, 30, 31,  0 ],
       [  0,  0, 32, 33,  0,  0 ]])

由于阵列具有不兼容的形状,这可能无法通过广播严格实现,但我希望有一种矢量化方法来实现此目的。

如果有方法可以使用masked_array数据结构也没关系,但我还没有在文档中找到任何建议有内置方法的内容。

4 个答案:

答案 0 :(得分:1)

它实际上是一线解决方案

import numpy as np

arr = np.array([[  0,  0,  1,  1,  0,  0 ],
   [  0,  1,  1,  1,  1,  0 ],
   [  1,  1,  1,  1,  1,  1 ],
   [  1,  1,  1,  1,  1,  1 ],
   [  0,  1,  1,  1,  1,  0 ],
   [  0,  0,  1,  1,  0,  0 ]])

xs = np.array([10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33])

arr[arr==1] = xs
arr
# outputs
array([[ 0,  0, 10, 11,  0,  0],
       [ 0, 12, 13, 14, 15,  0],
       [16, 17, 18, 19, 20, 21],
       [22, 23, 24, 25, 26, 27],
       [ 0, 28, 29, 30, 31,  0],
       [ 0,  0, 32, 33,  0,  0]])

答案 1 :(得分:1)

对于numpy数组,您可以使用条件对数组进行切片,以便为您的示例执行此操作:

import numpy as np

a = np.array([
   [  0,  0,  1,  1,  0,  0 ],
   [  0,  1,  1,  1,  1,  0 ],
   [  1,  1,  1,  1,  1,  1 ],
   [  1,  1,  1,  1,  1,  1 ],
   [  0,  1,  1,  1,  1,  0 ],
   [  0,  0,  1,  1,  0,  0 ]])

b = np.array([10, 11, 12, 13, 14, 15, 16, 
              17, 18, 19, 20, 21, 22, 23, 
              24, 25, 26, 27, 28, 29, 30, 
              31, 32, 33])

# all elements of a should be the elements of b
a[a==1] = b  # the number of ones in a must match the length of b
print(a)

[[ 0  0 10 11  0  0]
[ 0 12 13 14 15  0]
[16 17 18 19 20 21]
[22 23 24 25 26 27]
[ 0 28 29 30 31  0]
[ 0  0 32 33  0  0]]

答案 2 :(得分:1)

您可以使用布尔索引:

>>> import numpy as np
>>> mask = np.array([[  0,  0,  1,  1,  0,  0 ],
...        [  0,  1,  1,  1,  1,  0 ],
...        [  1,  1,  1,  1,  1,  1 ],
...        [  1,  1,  1,  1,  1,  1 ],
...        [  0,  1,  1,  1,  1,  0 ],
...        [  0,  0,  1,  1,  0,  0 ]])
>>> values = np.array([10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33])
>>> out = np.zeros(mask.shape, values.dtype)
>>> out[mask.astype(bool)] = values
>>> out
array([[ 0,  0, 10, 11,  0,  0],
       [ 0, 12, 13, 14, 15,  0],
       [16, 17, 18, 19, 20, 21],
       [22, 23, 24, 25, 26, 27],
       [ 0, 28, 29, 30, 31,  0],
       [ 0,  0, 32, 33,  0,  0]])

答案 3 :(得分:0)

这样做很危险,因为您需要假设y中的值与x中的1相同。

鉴于这是真的,那么你可以做以下

count = 0
for i in range(len(x)):
    for j in range(len(x[i])):
        if x[i][j] == 1:
            x[i][j] = y[count]
            count += 1