NumPy混合类型的数组/矩阵

时间:2014-07-18 19:48:54

标签: python arrays numpy matrix

我试图用混合数据类型(字符串,整数,整数)创建NumPy数组/矩阵(Nx3)。但是当我通过添加一些数据来附加此矩阵时,我收到一个错误: TypeError:无效的类型提升。拜托,有人可以帮我解决这个问题吗?

当我使用样本数据创建一个数组时,NumPy会将矩阵中的所有列投射到一个' S'数据类型。而且我无法为数组指定数据类型,因为当我这样做时 res = np.array([" TEXT",1,1],dtype =' S ,i4,i4') - 我收到错误: TypeError:预期可读缓冲区对象

templates.py

import numpy as np
from pprint import pprint

test_array = np.zeros((0, 3), dtype='S, i4, i4')
pprint(test_array)

test_array = np.append(test_array, [["TEXT", 1, 1]], axis=0)
pprint(test_array)

print("Array example:")
res = np.array(["TEXT", 1, 1])
pprint(res)

输出:

array([], shape=(0L, 3L), 
  dtype=[('f0', 'S'), ('f1', '<i4'), ('f2', '<i4')])

 Array example:
 array(['TEXT', '1', '1'], dtype='|S4')

错误:

Traceback (most recent call last):

File "templates.py", line 5, in <module>
test_array = np.append(test_array, [["TEXT", 1, 1]], axis=0)

File "lib\site-packages\numpy\lib\function_base.py", line 3543, in append
return concatenate((arr, values), axis=axis)

TypeError: invalid type promotion

5 个答案:

答案 0 :(得分:8)

您的问题出在数据中。试试这个:

res = np.array(("TEXT", 1, 1), dtype='|S4, i4, i4')

res = np.array([("TEXT", 1, 1), ("XXX", 2, 2)], dtype='|S4, i4, i4')

数据必须是元组或元组列表。从错误信息中不太明显,是吗?

另请注意,必须指定文本字段的长度才能真正保存文本数据。如果要将文本保存为对象(仅在数组中引用,则:

res = np.array([("TEXT", 1, 1), ("XXX", 2, 2)], dtype='object, i4, i4')

这通常也非常有用。

答案 1 :(得分:4)

如果你没有与numpy结婚,那么pandas DataFrame就是完美的。 或者,您可以将数组中的字符串字段指定为python对象(dtype =&#39; O,i4,i4&#39;作为示例)。附加似乎也喜欢元组列表,而不是列表列表。我认为它与列表的可变性有关,不确定。

答案 2 :(得分:2)

首先,numpy使用固定的物理记录大小存储数组元素。因此,记录对象需要具有相同的物理大小。因此,您需要告诉numpy字符串的大小或保存指向存储在其他位置的字符串的指针。在一个唱片阵列中,&#39; S&#39;转换为零长度的字符串,这可能不是你想要的。

append方法实际上将整个数组复制到更大的物理空间以容纳新元素。试试,例如:

import numpy as np
mtype = 'S10, i4, i4'
ta = np.zeros((0), dtype=mtype)
print id(ta)
ta = np.append(ta, np.array([('first', 10, 11)], dtype=mtype))
print id(ta)
ta = np.append(ta, np.array([('second', 20, 21)], dtype=mtype))
print id(ta)

每次以这种方式追加时,副本都会变慢,因为每次增长时都需要分配和复制更多内存。这就是每次追加时id返回不同值的原因。如果你想在你的数组中有大量的记录,你最好从一开始就分配足够的空间,或者在列表中累积数据,然后在你完成时将列表收集到一个numpy结构化数组中。这也让你有机会使mtype中的字符串长度尽可能短,同时仍然足够长,以保持最长的字符串。

答案 3 :(得分:1)

我认为这是您要完成的任务 - 创建所需dtype的空数组,然后向其中添加一个或多个数据集。结果将具有形状(N,),而不是(N,3)。

正如我在评论中指出的那样,np.append使用了np.concatenate,所以我也在使用它。此外,我必须同时制作test_arrayx 1d数组(分别为shape(0,)和(1,))。 dtype字段为S10,大小足以包含&#39; TEXT&#39;。

In [56]: test_array = np.zeros((0,), dtype='S10, i4, i4')

In [57]: x = np.array([("TEST",1,1)], dtype='S10, i4, i4')

In [58]: test_array = np.concatenate((test_array, x))

In [59]: test_array = np.concatenate((test_array, x))

In [60]: test_array
Out[60]: 
array([('TEST', 1, 1), ('TEST', 1, 1)], 
      dtype=[('f0', 'S'), ('f1', '<i4'), ('f2', '<i4')])

以下是从元组列表构建数组的示例:

In [75]: xl=('test',1,1)

In [76]: np.array([xl]*3,dtype='S10,i4,i4')
Out[76]: 
array([('test', 1, 1), ('test', 1, 1), ('test', 1, 1)], 
      dtype=[('f0', 'S10'), ('f1', '<i4'), ('f2', '<i4')])

答案 4 :(得分:-3)

我不相信你可以使用多种数据类型制作阵列。但是,您可以创建一个包含多种数据类型的列表。

list = ["TEXT", 1, 1]
print(list)

给出

['TEXT', 1, 1]