我正在尝试从python中的其他数组创建一个numpy结构化数组。然而,这并不像我期望的那样工作:
# this does what I want
In [3]: x = np.array([(1, 2), (3, 4)], dtype=[('foo', 'i8'), ('bar', 'f4')])
In [4]: x['foo']
Out[4]: array([1, 3])
In [5]: x['foo'].shape
Out[5]: (2,)
# when creating the array from another array, the structure is different
In [6]: y = np.array( np.array([(1, 2), (3, 4)]), dtype=[('foo', 'i8'), ('bar', 'f4')])
In [7]: y['foo'].shape
Out[7]: (2, 2)
# unpacking and packing into a list does not work either
In [8]: z = np.array([zz for zz in np.array([(1, 2), (3, 4)])], dtype=[('foo', 'i8'), ('bar', 'f4')])
In [9]: z['foo'].shape
Out[9]: (2, 2)
所以x
的结构化数组实现了我的期望和要求。但是当你使用另一个numpy数组时,我的应用程序需要它,结构就不同了。实际上你不能像x
那样访问轴。
解包值并将其打包也不起作用。
不幸的是,文档不够清楚(至少对我来说),关于如何做到这一点。欢呼
2条答案
按热度按时间zazmityj1#
有一个你应该熟悉的结构化数组文档页面。我现在就跳过为您查找链接。
通常,结构化数组的数据是作为元组列表提供的:
此输入回显显示和
tolist
。常规数组显示为列表的列表。选择元组表示法是为了清楚地定义结构化数组的records
。当你尝试生成
y
时,数组的每个元素都被“复制”以匹配dtype:通常这不是我们想要的。重申一下,内部数组的
tolist
不是一个元组列表:view
和astype
并没有更好地工作。然而,结构化数组文档讨论了
recfunctions
库。大多数是在recarrays
更常见的时候写的(现在pandas已经取代了很多时间序列的工作)。但是最近对结构化数组如何“切片”进行了一些修改,特别是对于多个字段,它增加了一些实用功能:
通常,
rf
函数创建一个具有所需复合dtype的目标数组,并逐个字段地将数据复制到其中。通常,记录的数量比字段的数量大得多,因此这种迭代复制相对有效。在任何情况下,在使用结构化数组时都要认真对待元组列表规范。
x6yk4ghg2#
可能有一个更聪明的方法(我从来不喜欢粗糙的或结构化的数组。我使用numpy来处理统一类型数据的传统单体数组。当我需要不同的类型或字段时,我会回到其他东西,比如pandas。所以,再一次,可能有更好的方法)。但在这里,我只是把你的尝试翻译成一个工作:
想法很简单:“如果它与元组一起工作,让它们有元组”:D
但是,也许有更好的想法
例如
也可以。而且可能更快。这是一个python循环。但它只在字段上完成,而前一个是在行上。通常你有更多的行比字段。
至于为什么它不能在数组中工作:理解你想要的结果不是一个2x2的2D数组,就像你的输入数组一样。它是一个2×1阵列,每个单元都是一个结构。为什么它仍然非常有效(numpy可以遍历每个字段,形状和步幅,与另一个数组一样有效。
所以你的第一行从数据开始,元组的一维列表,从中你构建了一个“结构”的一维数组。
您的其他尝试从2D数组开始。
定时
所以,编辑,同时我测试了一些时间,我确认了我的第一个观点:我的第二个代码更快。在我的假设下。行比字段多。从10000×2阵列开始,第一个代码的运行时间为8 ms,而第二个代码的运行时间为29 μs。
hpaulj回答后编辑
所以,正如我所想的,确实有一个更聪明的方法。即使我的python不让我直接运行他的代码,因为它需要一个合适的类型,而不是
[('foo', 'i8'), ('bar', 'f4')]
。但这很容易解决然而,时间方面,虽然几乎一样快,这种方法似乎(奇怪)比我的第二个慢。在我的同一个例子中,它需要39μs,而不是“空然后为字段”的29μs。
尽管如此,这还是在同一个数量级上(与构建元组列表的8毫秒相比),使用标准函数可能比重新发明轮子更好。