简体   繁体   English

赋值后numpy recarray的花式索引丢失了引用

[英]Fancy indexing of numpy recarray lost reference after assignment

I found a strange situation with my code and the issue is shown in the code bellow 我在代码中发现了一种奇怪的情况,该问题显示在下面的代码中

import numpy as np

dt = dict(names = ['n1','n2'], formats = ['a8','int'])
reca = np.recarray((10,), dtype = dt)
reca['n1'] = ['a','b','c','d','e','f','g','e','f','g']
reca['n2'] = range(10)

sreca = reca[::2]
print sreca[0] in reca

sreca[0]['n2'] = 12
print sreca[0] in reca

ireca = reca[[1,3,5,7]]
print ireca[0] in reca

ireca[0]['n2'] = 7
print ireca[0] in reca

The output is: 输出为:

True
True
True
False

To my understand, either sreca or ireca should keep a reference of reca unless i assign a new value to them directly, but ireca lost its reference after the assignment. 我的理解,无论是srecaireca应该保持的参考reca ,除非我直接将新值分配给他们,但ireca失去了分配后的参考。 I don't know if this is expected or not. 我不知道这是否可以预期。

Could any one advice me how to avoid this? 有人可以建议我如何避免这种情况吗?

BTW, I found that a small change of the code ( reca['n1'] = ['a']*10 for example) will give me all True in this sample, this really make me confused. 顺便说一句,我发现对代码进行少量更改( reca['n1'] = ['a']*10 )将使我在此示例中全部为True ,这确实使我感到困惑。

Using fancy indexing in a recarray will copy the data to a new array. recarray使用花式索引将把数据复制到新数组中。 Instead you could do: 相反,您可以执行以下操作:

ireca = [reca[i] for i in [1,3,5,7]]

since taking only one entry of the recarray keeps the reference. 因为只接受recarray的一项才能保留引用。 You can check when a new array has been created using the flags parameter: 您可以使用flags参数检查何时创建了新数组:

  • print(reca[0].flags) shows OWNDATA : False print(reca[0].flags)显示OWNDATA : False
  • print(reca[[0,1]].flags) shows OWNDATA : True print(reca[[0,1]].flags)显示OWNDATA : True

You first assigned to ireca the following components: 您首先为ireca分配了以下组件:

>>> ireca = reca[[1,3,5,7]]
>>> ireca 
rec.array([('b', 1), ('d', 3), ('f', 5), ('e', 7)], 
      dtype=[('n1', 'S8'), ('n2', '<i8')])

Then you assign to the first component in 'n2' instead of 1 , 7 and then you want to see whether it is still in the parent array reca or not and since the second component has changed then it is no longer in reca so you get False result. 然后分配给第一部分'n2' ,而不是17 ,然后你想看看它是否仍然在父阵列reca或不和,因为第二组分已经改变,那么它就不再在reca等你拿False结果。

>>> ireca[0]['n2']=7
>>> ireca[0]
('b', 7)
>>> ireca
rec.array([('b', 7), ('d', 3), ('f', 5), ('e', 7)], 
      dtype=[('n1', 'S8'), ('n2', '<i8')])

>>> print ireca[0] in reca
False

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM