使用Numpy并以良好的性能可以做到吗?
初始2D数组:
array([[0, 1, 1, 1, 1, 0],
[0, 0, 1, 0, 0, 0],
[1, 0, 0, 0, 0, 1]])
如果每行的总和小于4,则将每行的最后一项设置为1:
array([[0, 1, 1, 1, 1, 0],
[0, 0, 1, 0, 0, 1],
[1, 0, 0, 0, 0, 1]])
将每行中的每一项与每行的总和相除,得到这个 结果:
array([[0, 0.25, 0.25, 0.25, 0.25, 0],
[0, 0, 0.5, 0, 0, 0.5],
[0.5, 0, 0, 0, 0, 0.5]])
答案 0 :(得分:1)
您可以使用一些聪明的布尔索引在一行中进行条件赋值:
arr = np.array([[0, 1, 1, 1, 1, 0],
[0, 0, 1, 0, 0, 0],
[1, 0, 0, 0, 0, 1]])
arr[arr.sum(axis=1) < 4, -1] = 1
print(arr)
输出:
[[0 1 1 1 1 0]
[0 0 1 0 0 1]
[1 0 0 0 0 1]]
然后您可以像这样将每一行除以总和:
arr = arr / arr.sum(axis=1, keepdims=True)
print(arr)
输出:
[[0. 0.25 0.25 0.25 0.25 0. ]
[0. 0. 0.5 0. 0. 0.5 ]
[0.5 0. 0. 0. 0. 0.5 ]]
让我们将布尔索引数组arr.sum(axis=1) >= 4
命名为boolix
。 boolix
看起来像:
[ True False False]
如果用arr
对boolix
进行切片,它将返回一个数组,其中包含arr
的所有行,boolix
中的对应值为{{1} }。因此,True
的结果是一个数组,其中包含arr[boolix]
的第1
行和第2
行:
arr
在上面的代码中,[[0 0 1 0 0 0]
[1 0 0 0 0 1]]
被切片为arr
。在切片arr[boolix, -1]
中添加第二个索引将使切片仅包含每行中的最后一个值(即,最后一列中的值)。因此arr[anything, -1]
将返回:
arr[boolix, -1]
由于也可以将这些片分配给它们,因此将[0 1]
分配给片1
可解决您的问题。
答案 1 :(得分:1)
:numpy.where
在这里也可以找到符合您条件的行
import numpy as np
a = np.array([[0, 1, 1, 1, 1, 0],
[0, 0, 1, 0, 0, 0],
[1, 0, 0, 0, 0, 1]])
a[np.sum(a,axis=1) < 4, -1] = 1
a = a/a.sum(axis=1)[:,None]
print(a)
# Output
# [[0. 0.25 0.25 0.25 0.25 0. ]
# [0. 0. 0.5 0. 0. 0.5 ]
# [0.5 0. 0. 0. 0. 0.5 ]]
PS:@tel建议后编辑:)
答案 2 :(得分:0)
我认为您需要:
x = np.array([[0, 1, 1, 1, 1, 0],
[0, 0, 1, 0, 0, 0],
[1, 0, 0, 0, 0, 1]])
x[:,-1][x.sum(axis=1) < 4] = 1
# array([[0, 1, 1, 1, 1, 0],
# [0, 0, 1, 0, 0, 1],
# [1, 0, 0, 0, 0, 1]])
print(x/x.sum(axis=1)[:,None])
输出:
array([[0. , 0.25, 0.25, 0.25, 0.25, 0. ],
[0. , 0. , 0.5 , 0. , 0. , 0.5 ],
[0.5 , 0. , 0. , 0. , 0. , 0.5 ]])