【问题标题】:How to create a numpy matrix with differing column data types?如何创建具有不同列数据类型的 numpy 矩阵?
【发布时间】:2016-08-15 23:57:13
【问题描述】:

假设我有三个向量 abc

a = np.array([1,2,3])
b = np.array([1.2, 3.2, 4.5])
c = np.array([True, True, False])

将其转换为具有不同数据类型和列标签的矩阵d 的最简单方法是:

d = ([[1, 1.2, True],
     [2, 3.2, True], 
     [3, 4.5, False]], 
     dtype=[('aVals','i8'), ('bVals','f4'), ('cVals','bool')])

这样我就可以将此矩阵保存到.npy 文件中,并在打开它后访问数据;

>>> d = np.load('dFile')
>>> d['aVals']
np.array([1,2,3], dtype = [('aVals', '<i8)])

我使用 cimple column_stack 创建矩阵,但我在试图弄清楚如何包含数据类型和列名时感到头疼,因为 column_stack 不接受 dtype 参数,而我在执行column_stack 之后,看不到添加字段名称和数据类型的方法。值得一提的是,向量abc 在创建时没有明确的数据类型声明,如上所示。

【问题讨论】:

  • 顺便说一句,如果您这样做只是为了保存数组,您可以使用np.savez(outfile, aVals=a, bVals=b, cVals=c) 将所有三个数组保存到压缩的 npz 文件中。

标签: python arrays numpy


【解决方案1】:

有一个鲜为人知的recarray 函数可以构造这样的数组。它在最近的一个 SO 问题中被引用:

Assigning field names to numpy array in Python 2.7.3

允许它从输入数组中推断出所有内容:

In [19]: np.rec.fromarrays([a,b,c])
Out[19]: 
rec.array([(1, 1.2, True), (2, 3.2, True), (3, 4.5, False)], 
          dtype=[('f0', '<i4'), ('f1', '<f8'), ('f2', '?')])

指定名称

In [26]: d=np.rec.fromarrays([a,b,c],names=['avals','bvals','cVals'])
In [27]: d
Out[27]: 
rec.array([(1, 1.2, True), 
           (2, 3.2, True), 
           (3, 4.5, False)], 
          dtype=[('avals', '<i4'), ('bvals', '<f8'), ('cVals', '?')])
In [28]: d['cVals']
Out[28]: array([ True,  True, False], dtype=bool)

创建正确大小和 dtype 的目标数组后,它会逐字段复制。这是rec.recfunctions 的典型特征(甚至astype 也会这样做)。

# populate the record array (makes a copy)
for i in range(len(arrayList)):
    _array[_names[i]] = arrayList[i]

2011 年参考:How to make a Structured Array from multiple simple array

【讨论】:

  • 添加到 hpaulj 评论还有另一种简单的方法.... from numpy.lib._iotools import easy_dtype as easy ... easy((int, float, float), names="a, b,c") ... 产生 .... dtype([('a', '
  • easy_dtypegenfromtxt 用于将dtype 参数转换为更正式的dtypefromarrays 使用 np.rec.format_parser 进行翻译。
  • 谢谢你这是完美的,而且非常简单
【解决方案2】:
d = np.empty(len(a), dtype=[('aVals',a.dtype), ('bVals',b.dtype), ('cVals',c.dtype)])
d['aVals'] = a
d['bVals'] = b
d['cVals'] = c

作为一个可重用的函数:

def column_stack_overflow(**kwargs):
    dtype = [(name, val.dtype) for name, val in kwargs.items()]
    arr = np.empty(len(kwargs.values()[0]), dtype=dtype)
    for name, val in kwargs.items():
        arr[name] = val
    return arr

然后:

column_stack_overflow(aVals=a, bVals=b, cVals=c)

但请注意 kwargs 是一个如此无序的字典,因此您可能无法按照传递它们的顺序获取列。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-28
    • 1970-01-01
    • 1970-01-01
    • 2014-08-03
    • 1970-01-01
    • 2016-07-31
    • 1970-01-01
    相关资源
    最近更新 更多