Numpy,命名列

26

关于 numpy 的简单问题:

我将100个值加载到向量a中。从这个向量中,我想创建一个带有两列的数组A,其中一列名称为"C1",类型为int32,另一列名称为"C2",类型为int64。 例如:

a = range(100)
A = array(a).reshape( len(a)/2, 2)
# A.dtype = ...?

当我从a创建数组时,如何定义列的类型和名称?


你最好的选择是将数组(实际上两个)和名称列表封装到一个容器类中,然后使用它。 - Keith
@Keith:你是指特定的类吗?(我对numpy还不熟悉)? - Jakub M.
不,我是指你自己创建的数组。然后你可以从你新类中定义的方法中委托操作到你的数组。同时定义一个__str__方法,以带标题的方式漂亮地打印出你的数组。 - Keith
你需要将数据放在一个数组中吗?也就是说,你是否要一次性对整个数组执行操作(即使你声明每列需要不同的数据类型),还是要对每列执行不同的操作?如果是后者,也许没有理由将它们放在一个numpy数组中,而不是多个具有不同名称的不同数组。根据Keith的建议,你可以将这些单独的数组组合成一个类或命名元组。 - Daan
2个回答

24

NumPy结构化数组具有命名列:

import numpy as np
    
a = range(100)
A = np.array(list(zip(*[iter(a)] * 2)), dtype=[('C1', 'int32'),('C2', 'int64')])
print(A.dtype)
[('C1', '<i4'), ('C2', '<i8')]

你可以像这样通过名称访问列:

print(A['C1'])
# [ 0  2  4  6  8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48
#  50 52 54 56 58 60 62 64 66 68 70 72 74 76 78 80 82 84 86 88 90 92 94 96 98]

请注意,使用np.arrayzip一起会导致NumPy从临时元组列表构建数组。Python中的元组列表比等价的NumPy数组占用更多内存。因此,如果您的数组非常大,则可能不想使用zip

相反地,给定一个NumPy数组A,您可以使用ravel()A转换为1D数组,然后使用view将其转换为结构化数组,最后使用astype将列转换为所需类型:

a = range(100)
A = np.array(a).reshape( len(a)//2, 2)
A = A.ravel().view([('col1','i8'),('col2','i8'),]).astype([('col1','i4'),('col2','i8'),])
print(A[:5])
# array([(0, 1), (2, 3), (4, 5), (6, 7), (8, 9)], 
#       dtype=[('col1', '<i4'), ('col2', '<i8')])

print(A.dtype)
# dtype([('col1', '<i4'), ('col2', '<i8')])

你是正确的。http://docs.scipy.org/doc/numpy-1.4.x/reference/arrays.dtypes.html - Maxim Egorushkin
这是一个闪耀而非未知的技能,但令人惊讶的却不是常识,它应该广为人知。 - Ismael Harun

11

我知道这是一个老问题,但一个更近期的可用选项是尝试使用pandasDataFrame 类型针对结构化数据设计,例如此类数据,其中列是有命名且可以为不同类型。


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