使用putmask替换数组中列的值并保持顺序

3 投票
1 回答
1383 浏览
提问于 2025-04-16 18:24

我有一个包含浮点数的numpy数组,我想用一个公式重新计算一些新值,这个公式是根据正在重新计算的列来决定的。

我最开始尝试过循环遍历每一列,除了要重新计算的那一列,其他的都用掩码隐藏,然后用numpy.putmask把新值替换上去。但是这样做并不能保持顺序,因为它会试图把一个值放到每个元素上,如果失败了,就会尝试用下一个计算出来的值放到下一个元素上,像这样:

>>> import numpy as np

>>> x = [[  1.,   2.],
        [  3.,   4.],
        [  5.,   6.],
        [  7.,   8.],
        [  9.,  10.]]
>>> mask = [[ True, False],
           [ True, False],
           [ True, False],
           [ True, False],
           [ True, False]]
>>> y = [ 21.,  22.,  23.,  24.,  25.]
>>> np.putmask(x,mask,y)
>>> print x
[[ 21.   2.]
[ 23.   4.]
[ 25.   6.]
[ 22.   8.]
[ 24.  10.]]

我需要一个解决方案,能够在找到一个有效值之前,重复使用同一个值,这样x看起来会是:

[[ 21.   2.]
[ 22.   4.]
[ 23.   6.]
[ 24.   8.]
[ 25.  10.]]

欢迎任何解决方案或其他方法。谢谢。

1 个回答

2

putmask(x,mask,y) 这个函数的作用是,当 mask.flat[n] 为真(True)时,就把 y[n] 的值放到 x.flat[n] 里。

In [17]: list(x.flat)
Out[17]: [21.0, 2.0, 22.0, 4.0, 23.0, 6.0, 24.0, 8.0, 25.0, 10.0]

In [18]: list(mask.flat)
Out[18]: [True, False, True, False, True, False, True, False, True, False]

因为 mask.flat 的值是交替出现的真和假,所以你会发现 x.flat 中的每隔一个值会被 y 中的每隔一个值替换。

由于 y 的大小和 x 不一样,所以 y 中的值会重复使用。这就是为什么在调用 putmask(x,mask,y) 后,你会在 x 中看到不想要的交替值。

如果你想要在 mask 为真(True)的地方给 x 赋新值,那你只需要用 numpy 的索引方法 来进行赋值:

x[mask]=y

举个例子,

import numpy as np
x = np.array([[  1.,   2.],
        [  3.,   4.],
        [  5.,   6.],
        [  7.,   8.],
        [  9.,  10.]])
mask = np.array([[ True, False],
           [ True, False],
           [ True, False],
           [ True, False],
           [ True, False]])
y = np.array([ 21.,  22.,  23.,  24.,  25.])
x[mask]=y
print(x)
# [[ 21.   2.]
#  [ 22.   4.]
#  [ 23.   6.]
#  [ 24.   8.]
#  [ 25.  10.]]

撰写回答