更改tabular.tabarray或numpy.recarray的数据类型(dtype)

时间:2011-11-29 18:17:28

标签: python numpy

我希望将数据表示为Python中的电子表格。思考"好吧,有人确实写了这样一个模块!"我去了PyPI,在那里我找到了Tabular,它包含了NumPy的重排数据操作功能。大!可悲的是,当谈到字符串时,它似乎不像电子表格那样。

>>> import tabular as tb
>>> t = tb.tabarray(records=[('bork', 1, 3.5), ('stork', 2, -4.0)], names=['a','b','c'])
>>> t
tabarray([('bork', 1, 3.5), ('stork', 2, -4.0)], 
      dtype=[('a', '|S5'), ('b', '<i8'), ('c', '<f8')])
>>> t['a'][0] = 'gorkalork, but not mork'
>>> t
tabarray([('gorka', 1, 3.5), ('stork', 2, -4.0)], 
      dtype=[('a', '|S5'), ('b', '<i8'), ('c', '<f8')])

呃...... tabarray!你在那里截断我的字符串!真?! NumPy dtype&#39; | S5&#39; means是一个5个或更少字符的字符串,但加油!更新dtype。如果需要,重新格式化整个列。随你。但是不要悄悄地扔掉我的数据!

我尝试了其他几种方法,其中没有一种可以解决问题。例如,它确保了tabarray创建时的数据类型/大小,但在添加记录时却没有:

>>> t.addrecords(('mushapushalussh', 3, 4.44))
tabarray([('gorka', 1, 3.5), ('stork', 2, -4.0), ('musha', 3, 4.44)], 
      dtype=[('a', '|S5'), ('b', '<i8'), ('c', '<f8')])

我尝试切出整个列,更改其类型,设置值并重新分配:

>>> firstcol_long = firstcol.astype('|S15')
>>> firstcol_long
tabarray(['gorka', 'stork'], 
      dtype='|S15')
>>> firstcol_long[0] = 'morkapork'
>>> firstcol_long
tabarray(['morkapork', 'stork'], 
      dtype='|S15')
>>> t['a'] = firstcol_long
>>> t
tabarray([('morka', 1, 3.5), ('stork', 2, -4.0)], 
      dtype=[('a', '|S5'), ('b', '<i8'), ('c', '<f8')])
>>> 

它正确地进行了值赋值,但原始数据类型仍然有效,并且我以前正确的数据再次被静默截断。我甚至尝试了一种明确的数据类型设置:

>>> t = tb.tabarray(records=[('bork', 1, 3.5), ('stork', 2, -4.0)], dtype=[('a', str),('b', int),('c', float)])
>>> t
tabarray([('', 1, 3.5), ('', 2, -4.0)], 
      dtype=[('a', '|S0'), ('b', '<i8'), ('c', '<f8')])
好主啊!那更糟!它正确映射了intfloat类型,但它猜测str意味着我想要0长度字符串,并将所有数据截断为空。简而言之,不仅表格不像开箱即用的电子表格,我也找不到让它运作的方法。对我来说,性能不是一个大问题。我的电子表格可能有数百或数千行,最多,我很乐意让系统进行一些数据复制,以使我的代码更容易。 Tabular似乎在许多其他方面非常适合该法案。

我想我可以使用默认情况下将所有字符串默认为不可思议的大字段(例如1024或4096字节)的子表格,并使用__setitem__方法,如果分配更大的字符串,则会引发异常。相当邋...... ......但还有更好的选择吗?我扎根于numpy.recarray这样,有点,并没有看到一个明确的方式......但我会是第一个承认我完全不熟悉NumPy的人。实际情况是,数据操作程序可能会增加字符串的长度超过其初始最大值。当然,高功能模块应该适应这种情况。 &#34;只是截断它!&#34; 1974年面向记录的数据库中常见的方法在2011年不适合Python的最新技术!

思考和建议?

1 个答案:

答案 0 :(得分:2)

我不是想在这里粗鲁,但你误解了numpy是什么。

你不想要numpy。你想要一个dict

Numpy数组是不是通用数据容器。它们是统一数据的内存高效容器。整点是一个低级数据容器,它可以存储基本没有内存开销的东西(即100个64位浮点数使用800字节的内存作为numpy数组。它使用两次这样的一个清单。)

如果要存储非统一数据,请不要使用numpy数组。

Python拥有一组非常丰富的内置数据结构。在这种情况下,你想要的是字典或列表。