【问题标题】:How to insert column of different type to numpy array?如何将不同类型的列插入numpy数组?
【发布时间】:2019-06-14 04:16:33
【问题描述】:

我想将两个 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(尽管它可能是复合的)。
  • 虽然这不是问题,但不要养成使用np.append的习惯。这是一种使用 np.concatenate 的名称不佳的方式。
  • 感谢您对np.concatenate 的建议。您能否向 numpy 新手解释一下,为什么 np.concatenatenp.append 更好?提前致谢!
  • np.concatenate 是基本函数。查看np.append 的代码。它只是调整输入(只有 2 个)并调用 concatenate。但不仅如此,人们还倾向于滥用它,认为它就像附加列表一样。它不是。有几个stack 函数也使用concatenatenp.stack 可能是其中最有用的。但是你也可以看看他们的代码。

标签: python numpy


【解决方案1】:

可能最简单 - 使用 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 docs(或本网站上的其他 QA)。

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

一般来说,如果可以的话,你应该避免使用dtype=object 的数组。它们会导致许多基本 Numpy 操作(例如算术,例如 arr0 + arr1)出现性能问题,并且它们的行为方式可能出乎您的意料。

一个更好的仅 Numpy 解决方案是结构化数组。这些数组有一个复合 dtype,每个字段有一个部分(为了讨论,“字段”等同于“列”,尽管您 can do more interesting things with fields)。给定您的 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 数组一样。

【讨论】:

    【解决方案2】:

    考虑到其他用户的陈述,导致洞察力,将第一个数组转换为 dtype 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)
    

    【讨论】:

      猜你喜欢
      • 2013-03-07
      • 1970-01-01
      • 2022-12-21
      • 1970-01-01
      • 1970-01-01
      • 2019-06-21
      • 2017-03-07
      • 1970-01-01
      • 2021-11-13
      相关资源
      最近更新 更多