【问题标题】:Numpy "ma.where" has different behaviour from "where"... How can I make it behave the same?Numpy“ma.where”与“where”有不同的行为......我怎样才能让它表现得一样?
【发布时间】:2012-10-27 10:31:58
【问题描述】:

所以我尝试使用numpy.ma.where 为我创建一个数组,就像numpy.where 函数一样。 where 函数广播我的列数组,然后用零替换一些元素。我得到以下信息:

>>> import numpy
>>> condition = numpy.array([True,False, True, True, False, True]).reshape((3,2))
>>> print (condition)
[[ True False]
 [ True  True]
 [False  True]]
>>> broadcast_column = numpy.array([1,2,3]).reshape((-1,1)) # Column to be broadcast
>>> print (broadcast_column)
[[1]
 [2]
 [3]]
>>> numpy.where(condition, broadcast_column, 0) \
... # Yields the expected output, column is broadcast then condition applied
array([[1, 0],
       [2, 2],
       [0, 3]])
>>> numpy.ma.where(condition, broadcast_column, 0).data \
... # using the ma.where function yields a *different* array! Why?
array([[1, 0],
       [3, 1],
       [0, 3]], dtype=int32)
>>> numpy.ma.where(condition, broadcast_column.repeat(2,axis=1), 0).data \
... # The problem doesn't occur if broadcasting isnt used
array([[1, 0],
       [2, 2],
       [0, 3]], dtype=int32)

非常感谢您的帮助!

我的 numpy 版本是 1.6.2

【问题讨论】:

    标签: arrays numpy broadcast


    【解决方案1】:

    np.ma.where 的核心是声明: (在 Ubuntu 上,请参阅 /usr/share/pyshared/numpy/ma/core.py)

    np.putmask(_data, fc, xv.astype(ndtype))
    

    _data是要返回的掩​​码数组中的数据。

    fc 是布尔数组,条件为真时为真。

    xv.astype(ndtype) 是要插入的值,例如broadcast_column.

    In [90]: d = np.empty(fc.shape, dtype=ndtype).view(np.ma.MaskedArray)
    
    In [91]: _data = d._data
    
    In [92]: _data
    Out[92]: 
    array([[5772360, 5772360],
           [      0,      17],
           [5772344, 5772344]])
    
    In [93]: fc
    Out[93]: 
    array([[ True, False],
           [ True,  True],
           [False,  True]], dtype=bool)
    
    In [94]: xv.astype(ndtype)
    Out[94]: 
    array([[1],
           [2],
           [3]])
    
    In [95]: np.putmask(_data, fc, xv.astype(ndtype))
    
    In [96]: _data
    Out[96]: 
    array([[      1, 5772360],
           [      3,       1],
           [5772344,       3]])
    

    注意数组中间行的 3 和 1。

    问题是np.putmask 不广播值,它会重复它们:

    来自np.putmask 的文档字符串:

    putmask(a, 掩码, 值)

    mask.flat[n]==True 的每个n 设置a.flat[n] = values[n]

    如果values 的大小与amask 的大小不同,那么它将 重复。这给出了与a[mask] = values 不同的行为。

    当您显式广播时,flat 返回所需的展平值:

    In [97]: list(broadcast_column.repeat(2,axis=1).flat)
    Out[97]: [1, 1, 2, 2, 3, 3]
    

    但如果你不广播,

    In [99]: list(broadcast_column.flat) + list(broadcast_column.flat)
    Out[99]: [1, 2, 3, 1, 2, 3]
    

    正确的值不在所需的位置。


    PS。在最新版本的 numpy 中,the code reads

    np.copyto(_data, xv.astype(ndtype), where=fc)
    

    我不确定这对行为有什么影响;我没有足够新的 numpy 版本来测试。

    【讨论】:

    • 是的,你是对的,新版本的 numpy 可以正常工作,因为 copyto 会广播,抱歉...
    • @seberg:感谢您查看此内容。
    猜你喜欢
    • 2021-05-27
    • 1970-01-01
    • 2017-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-13
    • 2010-10-19
    • 1970-01-01
    相关资源
    最近更新 更多