如何将不同类型的列插入到numpy数组中?

3
我想将两个类型为np.datetime64int的numpy数组附加到另一个数组中。
这会导致错误。我该怎么做才能纠正这个错误?
如果我将向量附加到自身(即:np.append(c,c,axis=1)np.append(a,a,axis=1)),则不会出现错误。
numpy版本:1.14.3
import numpy as np
a = np.array([['2018-04-01T15:30:00'],
              ['2018-04-01T15:31:00'],
              ['2018-04-01T15:32:00'],
              ['2018-04-01T15:33:00'],
              ['2018-04-01T15:34:00']], dtype='datetime64[s]')
c = np.array([0,1,2,3,4]).reshape(-1,1)
c
Out[2]: 
array([[0],
       [1],
       [2],
       [3],
       [4]])
d = np.append(c,a,axis=1)
Traceback (most recent call last):
  File "/home/user/anaconda3/lib/python3.6/site-packages/IPython/core/interactiveshell.py", line 2963, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-3-10548a83d1a2>", line 1, in <module>
    d = np.append(c,a,axis=1)
  File "/home/user/anaconda3/lib/python3.6/site-packages/numpy/lib/function_base.py", line 5166, in append
    return concatenate((arr, values), axis=axis)
TypeError: invalid type promotion

你期望的 dtypeshape 是什么?请记住,NumPy 数组只有一个 dtype(尽管它可能是复合类型)。 - hpaulj
虽然这里不是问题所在,但不要养成使用np.append的习惯。这是一种使用np.concatenate的名称不当的方式。 - hpaulj
感谢您关于 np.concatenate 的建议。您能否向一个numpy新手解释为什么np.concatenatenp.append更好?提前感谢! - user7468395
np.concatenate 是基础函数。看一下 np.append 的代码。它只是调整了输入(只有两个),然后调用 concatenate。但更重要的是,人们往往会误用它,认为它就像列表的 append 一样。它不是。还有几个使用 concatenatestack 函数。np.stack 可能是其中最有用的。但你也可以看看它们的代码。 - hpaulj
2个回答

4

可能最简单的方法 - 使用Pandas DataFrame而不是数组

实际上,尽管Numpy数组可以用于处理异构列,但在大多数情况下,它们可能并不是用户实际需要的。对于许多用例,您可能更好地使用Pandas DataFrame。以下是将两列转换为名为dfDataFrame的方法:

import numpy as np
import pandas as pd

a = np.array([['2018-04-01T15:30:00'],
              ['2018-04-01T15:31:00'],
              ['2018-04-01T15:32:00'],
              ['2018-04-01T15:33:00'],
              ['2018-04-01T15:34:00']], dtype='datetime64[s]')
c = np.array([0,1,2,3,4]).reshape(-1,1)


df = pd.DataFrame(dict(date=a.ravel(), val=c.ravel()))
print(df)
# output:
#                      date  val
#     0 2018-04-01 15:30:00    0
#     1 2018-04-01 15:31:00    1
#     2 2018-04-01 15:32:00    2
#     3 2018-04-01 15:33:00    3
#     4 2018-04-01 15:34:00    4

您可以这样处理每一列:
print(df['date'])
# output:
#     0   2018-04-01 15:30:00
#     1   2018-04-01 15:31:00
#     2   2018-04-01 15:32:00
#     3   2018-04-01 15:33:00
#     4   2018-04-01 15:34:00
#     Name: date, dtype: datetime64[ns]

DataFrame对象提供了大量方法,使得分析这种数据变得相当容易。有关DataFrame对象的更多信息,请参见Pandas文档(或此站点上的其他问答)。

Numpy仅解决方案 - 结构化数组

通常情况下,如果可以的话,应该避免使用dtype=object的数组。它们会导致许多基本的Numpy操作(例如算术运算,如arr0 + arr1)的性能问题,并且它们可能表现出您不希望看到的行为。

更好的Numpy仅解决方案是结构化数组。这些数组具有复合dtype,每个字段都有一个部分(对于本讨论而言,“字段”等同于“列”,但您可以使用字段进行更有趣的操作)。给定您的ac数组,以下是如何创建结构化数组的方法:

# create the compound dtype
dtype = np.dtype(dict(names=['date', 'val'], formats=[arr.dtype for arr in (a, c)]))

# create an empty structured array
struct = np.empty(a.shape[0], dtype=dtype)

# populate the structured array with the data from your column arrays
struct['date'], struct['val'] = a.T, c.T

print(struct)
# output:
#     array([('2018-04-01T15:30:00', 0), ('2018-04-01T15:31:00', 1),
#            ('2018-04-01T15:32:00', 2), ('2018-04-01T15:33:00', 3),
#            ('2018-04-01T15:34:00', 4)],
#           dtype=[('date', '<M8[s]'), ('val', '<i8')])

你可以通过使用列名进行索引(就像你可以使用DataFrame一样)来访问特定的列:
print(struct['date'])
# output:
#     ['2018-04-01T15:30:00' '2018-04-01T15:31:00' '2018-04-01T15:32:00'
#      '2018-04-01T15:33:00' '2018-04-01T15:34:00']

结构化数组的陷阱

例如,您不能将两个结构化数组相加:

# doesn't work
struct0 + struct1

但是您可以添加两个结构化数组的字段:

# works great
struct0['val'] + struct1['val']

一般而言,这些字段的行为与标准的Numpy数组类似。

0
考虑其他用户的陈述,可以得出结论,将第一个数组转换为object类型至少是一种解决方法。
import numpy as np
a = np.array([['2018-04-01T15:30:00'],
       ['2018-04-01T15:31:00'],
       ['2018-04-01T15:32:00'],
       ['2018-04-01T15:33:00'],
       ['2018-04-01T15:34:00']], dtype='datetime64[s]')
a = a.astype("object")
c = np.array([0,1,2,3,4]).reshape(-1,1)
d = np.append(a,c,axis=1)
d

.

array([[datetime.datetime(2018, 4, 1, 15, 30), 0],
   [datetime.datetime(2018, 4, 1, 15, 31), 1],
   [datetime.datetime(2018, 4, 1, 15, 32), 2],
   [datetime.datetime(2018, 4, 1, 15, 33), 3],
   [datetime.datetime(2018, 4, 1, 15, 34), 4]], dtype=object)

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