理解Python numpy数组的视图/副本:为什么双布尔索引不起作用?

时间:2017-11-06 21:03:20

标签: python arrays numpy boolean-operations

我正在阅读http://scipy-cookbook.readthedocs.io/items/ViewsVsCopies.html(和http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy)并尝试理解为什么Python不会尝试以直观的方式解释下面的最后一行,

<script>
    function dosubmit(form) {
        $.ajax({
            async: false,    // make ajax not async
            url: $(form).attr('action'),
            type: 'post',
            data: $(form).serializeArray()
        }).done(function (data) {
            form.submit();
        }).fail(function (data) {
            alert('error');
        });
        return false;
    }
</script>

,也就是说,Python神,更新第一个第二个布尔数组掩盖的import numpy as np import pandas as pd n = 100 tested = np.zeros(n, dtype=bool) dt = pd.DatetimeIndex([pd.datetime(2000, 1, 1, 0, 0, 0, 0) + pd.Timedelta(minutes=idx) for idx in range(n)]) data = np.random.normal(size=n) data[np.random.uniform(size=n) > 0.9] = np.nan mask = np.isnan(data) dt_ = dt[~mask] data_ = data[~mask] select = pd.DatetimeIndex(dt_) > pd.datetime(2000, 1, 1, 1, 0, 0) data__ = data_[select] # do something with this later, otherwise, why mask? tested[~mask][select] = True # or np.ones(select.sum(), dtype=bool) 元素。令人讨厌的是,第一个布尔掩码返回tested数组的副本(感谢catch @ user2357112),当被第二个索引和更新时,它不会写入结果回到原始数组。我认为我是对的是说其他一些解释语言使用这种语法,为什么不在这里呢?或者也许有一些我无法正确理解的计算机科学最佳实践?实际发生的是tested仍然是所有tested的布尔矢量。

1 个答案:

答案 0 :(得分:0)

同时使用maskselect的关键是将~mask更改为索引,并将select应用于该数组。

print(select.shape)
print(data__.shape)

idx = np.where(~mask)[0]
tested[idx[select]] = True
print(tested.sum())

生产一次运行:

(92,)
(34,)
34

我发现时序测试data[mask]实际上是data[np.where(mask)],所以使用数组选择而不是布尔掩码没有功率损失。

如果经常发生这种双重屏蔽,numpy开发人员可以将这些代码打包在函数中,即使在编译代码中也是如此。

data[mask][select] = 1   # translates to:
data.__getitem__(mask).__setitem__(select, 1)

是一致的Python语法。如果您需要不同的解释器操作,例如:

data.__setitem__(<foo(mask, select)>, 1)

编写一个PEP,并说服其他Python开发人员这是一个好主意。