numpy boolean indexing选择和设置

时间:2017-12-06 08:42:39

标签: python numpy

我对python不是很熟悉。我读过“数据分析用Python”这本书。最近,我对numpy布尔索引和设置有点困惑。 书上说:

  

通过布尔索引从数组中选择数据总是会创建数据的副本,即使返回的数组未更改。

     

使用布尔数组设置值以常识方式工作。

我已尝试过以下代码:

首先:

data = np.random.randn(7, 4) 
data[data < 0] = 0 # this could change the `data`

第二

data = np.random.randn(7, 4) 
copied = data[data < 0]
copied[1] = 1  # this couldn't change the `data`

我在这里不太明白,任何人都可以解释。根据我的理解,copied应该是指向数据的指针[data&lt; 0]切片。

3 个答案:

答案 0 :(得分:2)

虽然data[data < 0] = 0 sorta看起来像是设置为0的视图,但这不是实际发生的事情。实际上,ndarray后跟=来电__setitem__来处理分段分配。

当ndarray位于=的另一侧时,__setitem__未被调用,并且您指定了一个副本(如布尔索引总是这样),它独立于原始数组。 / p>

本质:

foo[foo != bar] = bar                # calls __setitem__
foo[:2]         = bar                # calls __setitem__
bar             = foo[foo != bar]    # makes a copy
bar             = foo[:2]            # makes a view

答案 1 :(得分:2)

根据经验,numpy会尽可能创建视图,并在必要时创建副本。

何时可以查看?当可以使用步幅来寻址数据时,即例如对于2d阵列A,每个A[i, j]位于地址base + i*stride[0] + j*stride[1]的存储器中。如果您仅使用切片创建一个子阵列,那么这将是您获得视图的原因。

对于逻辑和高级索引,通常无法找到恰好解决正确元素的基础和步幅。因此,这些操作返回一个复制了数据的新数组。

答案 2 :(得分:0)

基于代码序列:

  1. data = np.random.randn(7, 4):Thi step创建一个大小为7乘4的数组
  2. data[data < 0] = 0:使数据中的所有元素都是&lt; 0为0
  3. copied = data[data < 0]:此步骤生成一个空数组,因为数据中没有&lt; 0,因为步骤4
  4. copied[1] = 1:此步骤引发错误,因为复制是一个空数组,因此索引1不存在