在一个NumPy数组中存储不同的数据类型?

70
我有两个不同的数组,一个包含字符串,另一个包含整数。我想将它们连接成一个数组,其中每列都具有原始的数据类型。我目前使用的解决方案(如下所示)会将整个数组转换为dtype = string,这似乎非常浪费内存。 combined_array = np.concatenate((A, B), axis = 1)A.dtype = stringB.dtype = int时,是否可以在combined_array中使用多个数据类型?

5
问题是关于使用NumPy数组。但是,如果没有必要使用NumPy数组,那么Pandas DataFrame在这种情况下也可以很好地工作。 - crayzeewulf
3个回答

56
一种方法可能是使用记录数组。 "列"不会像标准的numpy数组的列那样,但对于大多数用例来说,这已经足够了。
>>> a = numpy.array(['a', 'b', 'c', 'd', 'e'])
>>> b = numpy.arange(5)
>>> records = numpy.rec.fromarrays((a, b), names=('keys', 'data'))
>>> records
rec.array([('a', 0), ('b', 1), ('c', 2), ('d', 3), ('e', 4)], 
      dtype=[('keys', '|S1'), ('data', '<i8')])
>>> records['keys']
rec.array(['a', 'b', 'c', 'd', 'e'], 
      dtype='|S1')
>>> records['data']
array([0, 1, 2, 3, 4])

请注意,您也可以通过指定数组的数据类型来使用标准数组执行类似操作。这被称为"结构化数组"。
>>> arr = numpy.array([('a', 0), ('b', 1)], 
                      dtype=([('keys', '|S1'), ('data', 'i8')]))
>>> arr
array([('a', 0), ('b', 1)], 
      dtype=[('keys', '|S1'), ('data', '<i8')])

不同之处在于记录数组还允许对单个数据字段进行属性访问,而标准结构化数组则不允许。

>>> records.keys
chararray(['a', 'b', 'c', 'd', 'e'], 
      dtype='|S1')
>>> arr.keys
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'numpy.ndarray' object has no attribute 'keys'

2
arr = np.array([('猫', 5), ('狗', 20)], dtype=[('name', np.object), ('age',np.int)]) 结构化数组中可以通过 arr['name'] 访问名称列。 - Bharath Ram

13

一个简单的解决方案:将您的数据转换为对象“O”类型

z = np.zeros((2,2), dtype='U2')
o = np.ones((2,1), dtype='O')
np.hstack([o, z])

创建数组:

array([[1, '', ''],
       [1, '', '']], dtype=object)

8
如果您真的想对该数组的切片进行任何有意义的操作,这会在后续过程中引起各种问题。 - Astrid
3
什么样的问题? - matthieu
1
@Astrid,你能详细阐述一下你的想法吗? - flow2k
5
假设,举个例子,你将它转换成了一个数据框。然后你想要过滤数据框中的对象,比如 df.loc[(df.col == item)],那么这是行不通的,因为在进行筛选时,Pandas 要求所有的项都是相同类型的。例如,如果你将字符串和整数混合在同一列中,那么实际上你在比较苹果和橙子。因此,Pandas 会报错。 - Astrid

3
参考Numpy文档,有一个名为numpy.lib.recfunctions.merge_arrays的函数,可以用于将不同数据类型的numpy数组合并成结构化数组或记录数组。
示例:
>>> from numpy.lib import recfunctions as rfn
>>> A = np.array([1, 2, 3])
>>> B = np.array(['a', 'b', 'c'])
>>> b = rfn.merge_arrays((A, B))
>>> b
array([(1, 'a'), (2, 'b'), (3, 'c')], dtype=[('f0', '<i4'), ('f1', '<U1')])

请参考上面的链接以获取更详细的信息。

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