我看到一些我不理解的布尔索引行为,我希望在这里找到一些澄清。
首先,这是我正在寻找的行为......
>>>
>>> a = np.zeros(10, dtype=np.ndarray)
>>> a
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=object)
>>> b = np.arange(10).reshape(2,5)
>>> b
array([[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9]])
>>> a[5] = b
>>> a
array([0, 0, 0, 0, 0, array([[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9]]), 0,
0, 0, 0], dtype=object)
>>>
选择ndarray的ndarray的原因是因为我将追加存储在超级数组中的数组,并且它们将具有不同的长度。我为超级数组选择了类型ndarray而不是list,所以我可以访问所有numpys聪明的索引功能。
无论如何,如果我创建一个布尔索引器并使用它来指定位置1处的b + 5,它会做一些我没想到的事情
>>> indexer = np.zeros(10,dtype='bool')
>>> indexer
array([False, False, False, False, False, False, False, False, False, False], dtype=bool)
>>> indexer[1] = True
>>> indexer
array([False, True, False, False, False, False, False, False, False, False], dtype=bool)
>>> a[indexer] = b+5
>>> a
array([0, 5, 0, 0, 0, array([[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9]]), 0,
0, 0, 0], dtype=object)
>>>
任何人都可以帮我理解发生了什么吗?我希望结果是
>>> a[1] = b+5
>>> a
array([0, array([[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]]), 0, 0,
0, array([[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9]]), 0, 0, 0, 0], dtype=object)
>>>
最终目标是在B中存储大量“b”数组,并将它们分配给这样的
>>> a[indexer] = B[indexer]
编辑:
根据下面的讨论找到了可能的解决方法。如果我需要
,我可以将我的数据包装在一个类中>>>
>>> class myclass:
... def __init__(self):
... self.data = np.random.rand(1)
...
>>>
>>> b = myclass()
>>> b
<__main__.myclass object at 0x000002871A4AD198>
>>> b.data
array([ 0.40185378])
>>>
>>> a[indexer] = b
>>> a
array([None, <__main__.myclass object at 0x000002871A4AD198>, None, None,
None, None, None, None, None, None], dtype=object)
>>> a[1].data
array([ 0.40185378])
编辑: 这实际上失败了。索引
时,我无法为数据字段分配任何内容答案 0 :(得分:1)
In [203]: a = np.empty(5, object)
In [204]: a
Out[204]: array([None, None, None, None, None], dtype=object)
In [205]: a[3]=np.arange(3)
In [206]: a
Out[206]: array([None, None, None, array([0, 1, 2]), None], dtype=object)
如此简单的索引与此对象数组一起使用。
布尔索引适用于阅读:
In [207]: a[np.array([0,0,0,1,0], dtype=bool)]
Out[207]: array([array([0, 1, 2])], dtype=object)
In [208]: a[np.array([0,0,1,0,0], dtype=bool)]
但写作时遇到问题:
Out[208]: array([None], dtype=object)
In [209]: a[np.array([0,0,1,0,0], dtype=bool)]=np.arange(2)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-209-c1ef5580972c> in <module>()
----> 1 a[np.array([0,0,1,0,0], dtype=bool)]=np.arange(2)
ValueError: NumPy boolean array indexing assignment cannot assign 2
input values to the 1 output values where the mask is true
np.where(<boolean>)
和[2]
也会出现问题:
In [221]: a[[2]]=np.arange(3)
/usr/local/bin/ipython3:1: DeprecationWarning: assignment will raise an
error in the future, most likely because your index result shape does
not match the value array shape. You can use `arr.flat[index] = values`
to keep the old behaviour.
无论出于何种原因,对对象dtype数组的索引赋值都不如常规的那样有效。
即使是推荐的flat
也无效
In [226]: a.flat[[2]]=np.arange(3)
In [227]: a
Out[227]: array([None, None, 0, array([0, 1, 2]), None], dtype=object)
我可以指定一个非列表/数组对象
In [228]: a[[2]]=None
In [229]: a
Out[229]: array([None, None, None, array([0, 1, 2]), None], dtype=object)
In [230]: a[[2]]={3:4}
In [231]: a
Out[231]: array([None, None, {3: 4}, array([0, 1, 2]), None], dtype=object)
In [232]: idx=np.array([0,0,1,0,0],bool)
In [233]: a[idx]=set([1,2,3])
In [234]: a
Out[234]: array([None, None, {1, 2, 3}, array([0, 1, 2]), None], dtype=object)
object
dtype数组位于numpy
数组功能的边缘。
查看我们使用getitem
获得的内容。使用标量索引,我们可以获得该槽中存储的对象(在我最新的情况下,为set
)。但是使用[[2]]
或布尔值,我们得到另一个对象数组。
In [235]: a[2]
Out[235]: {1, 2, 3}
In [236]: a[[2]]
Out[236]: array([{1, 2, 3}], dtype=object)
In [237]: a[idx]
Out[237]: array([{1, 2, 3}], dtype=object)
In [238]: a[idx].shape
Out[238]: (1,)
我怀疑当a[idx]
在LHS上时,它会尝试首先将RHS转换为对象数组:
Out[241]: array([0, 1, 2], dtype=object)
In [242]: _.shape
Out[242]: (3,)
In [243]: np.array(set([1,2,3]), object)
Out[243]: array({1, 2, 3}, dtype=object)
In [244]: _.shape
Out[244]: ()
在set
的情况下,结果数组有一个元素,可以放在(1,)槽中。但是当RHS是列表或数组时,结果是n个元素数组,例如(3,),它不适合(1,)槽。
如果要使用某种形式的高级索引(布尔值或列表)将列表/数组分配给对象数组中的插槽,请先将该项放入正确大小的对象数组中:
In [255]: b=np.empty(1,object)
In [256]: b[0]=np.arange(3)
In [257]: b
Out[257]: array([array([0, 1, 2])], dtype=object)
In [258]: b.shape
Out[258]: (1,)
In [259]: a[idx]=b
In [260]: a
Out[260]: array([None, None, array([0, 1, 2]), array([0, 1, 2]), None], dtype=object)
或使用稍大的数组:
In [264]: a = np.zeros(10, dtype=object)
In [265]: b = np.arange(10).reshape(2,5)
In [266]: a[5] = b
In [267]: c = np.zeros(1, dtype=object) # intermediate object wrapper
In [268]: c[0] = b+5
In [269]: idx = np.zeros(10,bool)
In [270]: idx[1]=True
In [271]: a[idx] = c
In [272]: a
Out[272]:
array([0, array([[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]]), 0, 0,
0, array([[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9]]), 0, 0, 0, 0], dtype=object)
如果idx
有n个True项,则c
必须具有将广播到(n,)的形状