Numpy中没有结构化数组的二元运算符?

use*_*194 8 python numpy binary-operators structured-array

好的,所以在浏览了numpy结构化数组的教程后,我能够创建一些简单的例子:

from numpy import array, ones
names=['scalar', '1d-array', '2d-array']
formats=['float64', '(3,)float64', '(2,2)float64']
my_dtype = dict(names=names, formats=formats)
struct_array1 = ones(1, dtype=my_dtype)
struct_array2 = array([(42., [0., 1., 2.], [[5., 6.],[4., 3.]])], dtype=my_dtype)
Run Code Online (Sandbox Code Playgroud)

(我的预期用例将有三个以上的条目,并将使用非常长的1d阵列.)因此,一切顺利,直到我们尝试执行一些基本的数学运算.我得到以下所有错误:

struct_array1 + struct_array2
struct_array1 * struct_array2
1.0 + struct_array1
2.0 * struct_array2
Run Code Online (Sandbox Code Playgroud)

显然,即使是最简单的结构化数组也不支持简单的运算符(+, - ,*,/).或者我错过了什么?我是否应该看一些其他的包裹(并且不要说熊猫,因为它完全过度杀戮)?这似乎是一个显而易见的能力,所以我有点傻眼.但是很难在网上找到任何有关此问题的喋喋不休.这不会严重限制结构化数组的有用性吗?为什么有人会使用结构数组而不是数组打包到dict中?是否存在技术上的原因导致这种情况难以解决?或者,如果正确的解决方案是执行重载的艰巨工作,那么如何在保持操作快速的同时完成?

hpa*_*ulj 3

对整个数组进行操作的另一种方法是使用文档中描述的“union”数据类型。在您的示例中,您可以通过添加“联合”字段并指定重叠的“偏移”来扩展数据类型:

from numpy import array, ones, zeros

names=['scalar', '1d-array', '2d-array', 'union']
formats=['float64', '(3,)float64', '(2,2)float64', '(8,)float64']
offsets=[0, 8, 32, 0]
my_dtype = dict(names=names, formats=formats, offsets=offsets)
struct_array3=zeros((4,), dtype=my_dtype)
Run Code Online (Sandbox Code Playgroud)

['union'](n,8)现在可以以数组的形式访问所有数据

struct_array3['union'] # == struct_array3.view('(8,)f8')
struct_array3['union'].shape  # (4,8)
Run Code Online (Sandbox Code Playgroud)

您可以对“union”或任何其他字段进行操作:

struct_array3['union'] += 2
struct_array3['scalar']= 1
Run Code Online (Sandbox Code Playgroud)

“union”字段可以是其他兼容的形状,例如'(2,4)float64'. 这样的数组的“行”可能如下所示:

array([ (3.0, [0.0, 0.0, 0.0], [[2.0, 2.0], [0.0, 0.0]], 
      [[3.0, 0.0, 0.0, 0.0], [2.0, 2.0, 0.0, 0.0]])], 
      dtype={'names':['scalar','1d-array','2d-array','union'], 
             'formats':['<f8',('<f8', (3,)),('<f8', (2, 2)),('<f8', (2, 4))], 
             'offsets':[0,8,32,0], 
             'itemsize':64})
Run Code Online (Sandbox Code Playgroud)