通过引用实现的Numpy嵌套结构化数组

4

我有以下的数据结构:

N=100
TB =     {'names':('n', 'D'),'formats':(int, int)}
TA =     {'names':('id', 'B'),'formats':(int, dtype((TB, (N))))}
a = np.empty(1000, dtype=TA)
b = np.empty(N, dtype=TB)

其中a是一个有两个字段'id'和'B'的结构化数组。在'B'中存储了另一个有'n'和'D'字段的结构化数组,例如:

for i in range(0,1000):
   a['B'][i] = b

当执行以上赋值语句时,会将b中的数据复制到a中。有没有一种方法只复制对b的引用,这样当我改变b时,a['B'][i]也会反映出此更改?我的目标是在a中存储对b的指针,因为对于a的每一行来说,b中的数据是相同的,所以不需要创建副本。
我尝试过。
TA = {'names':('id', 'B'),'formats':(int, object)}

它可以正常工作,但会破坏数组的嵌套结构。是否有方法保留结构化数组功能,例如 a['B']['D']

谢谢

2个回答

4
短答案是不行的。虽然numpy数组的语法看起来与标准python语法相同,但背后发生的事情却大不相同。像TA这样的复杂numpy数据类型使用大块连续的内存来存储每个记录;内存必须定期布局,否则一切都会分崩离析。
因此,当您创建一个具有类似TA的嵌套数据类型的1000项数组时,实际上您正在分配1000个内存块,每个内存块足够大,可以包含N个不同的TB数组。这正是您可以执行a['B']['D']之类的操作的原因-或者说,像这样的操作:
>>> (a['B'][1]['D'] == a['B']['D'][1]).all()
True
>>> a['B'][1]['D'][0] = 123456789
>>> (a['B'][1]['D'] == a['B']['D'][1]).all()
True

对于普通的Python对象来说,上述操作将失败,因为对象项访问顺序很重要。实际上,在numpy中这是可能的,而且唯一的原因是numpy使用统一结构连续存储器。据我所知,numpy没有提供任何方法来实现您要求的功能(如果我错了,请有人纠正我!),所需的间接操作可能需要对numpy的API进行重大更改。我想补充一下,即使可以只需要一个数组的副本,也不太合理。如果只需要数组外部存储,为什么不直接存储?您甚至可以将其与numpy数组一起传递,作为元组或命名元组的一部分。

谢谢您的回复。我之前没有考虑过访问顺序,现在我明白了您的观点。我也考虑过使用命名元组,但从接口的角度来看,“纯”结构化数组解决方案仍然是可取的。经过一些尝试和错误,我已将问题分解为以下内容:asdsd。 - maryam roayaee
经过一些尝试和错误,我已将问题分解为以下内容:A=np.ones(10); AA=np.empty(1, dtype=object); AA[0]=np.ones(10)。如果可以使用AA.view()或AA.astype()将AA转换为A的类型/数据类型,则可以得到解决方案,但到目前为止我还没有找到方法。 - maryam roayaee

0

是的,你可以只打开一个视图。但它也可以像你描述的那样反过来工作:

>>> a = np.array([1,2,3,4,5,6])
>>> b = a[2:4].view()
>>> b[0] = 0
>>> b[1] = 0
>>> a
array([1, 2, 0, 0, 5, 6])

将一个视图赋值给一个结构化数组也会复制数据,所以您的建议行不通。解决方法是创建一个 dtype=object 类型的数组,但是有没有一种方法可以将这样一个数组的视图转换/打开为原始 dtype? - maryam roayaee
Maryam,视图不会复制数据。它是对内存中相同区域的引用,其中包含数据。 - Davoud Taghawi-Nejad
当您将其传递给结构化数组时不会如此:A=np.zeros(1,dtype='int,10int'); B=np.arange(10); A['f1']=B.view(); B*=0; print B; print A - maryam roayaee
比较一下:AA=np.zeros(1,dtype='int,object'); B=np.arange(10); AA['f1'][0]=B; B*=0; print B; print AA 现在我正在寻找一种将 AA 转换/视图类似 A 的方法。 - maryam roayaee

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接