14

我有一个起始数组,例如:

[(1, [-112.01268501699997, 40.64249414272372])
 (2, [-111.86145708699996, 40.4945008710162])]

第一列是一个int,第二列是一个listfloats我需要添加一个str名为'USNG'.

然后我创建一个结构化的 numpy 数组,如下所示:

dtype = numpy.dtype([('USNG', '|S100')])
x = numpy.empty(array.shape, dtype=dtype)

我想将xnumpy 数组作为新列附加到现有数组中,因此我可以为每一行向该列输出一些信息。

当我执行以下操作时:

numpy.append(array, x, axis=1)

我收到以下错误:

'TypeError: invalid type promotion'

我也试过vstackhstack

4

6 回答 6

15

您必须创建一个包含新字段的新 dtype。

例如,这里是a

In [86]: a
Out[86]: 
array([(1, [-112.01268501699997, 40.64249414272372]),
       (2, [-111.86145708699996, 40.4945008710162])], 
      dtype=[('i', '<i8'), ('loc', '<f8', (2,))])

a.dtype.descr[('i', '<i8'), ('loc', '<f8', (2,))];即字段类型列表。我们将通过添加('USNG', 'S100')到该列表的末尾来创建一个新的 dtype:

In [87]: new_dt = np.dtype(a.dtype.descr + [('USNG', 'S100')])

现在创建一个的结构化数组,b. 我zeros在这里使用,所以字符串字段将以 value 开头''。你也可以使用empty. 然后这些字符串将包含垃圾,但如果您立即为它们赋值,这并不重要。

In [88]: b = np.zeros(a.shape, dtype=new_dt)

将现有数据复制ab

In [89]: b['i'] = a['i']

In [90]: b['loc'] = a['loc']

现在是b

In [91]: b
Out[91]: 
array([(1, [-112.01268501699997, 40.64249414272372], ''),
       (2, [-111.86145708699996, 40.4945008710162], '')], 
      dtype=[('i', '<i8'), ('loc', '<f8', (2,)), ('USNG', 'S100')])

用一些数据填写新字段:

In [93]: b['USNG'] = ['FOO', 'BAR']

In [94]: b
Out[94]: 
array([(1, [-112.01268501699997, 40.64249414272372], 'FOO'),
       (2, [-111.86145708699996, 40.4945008710162], 'BAR')], 
      dtype=[('i', '<i8'), ('loc', '<f8', (2,)), ('USNG', 'S100')])
于 2014-08-21T14:51:54.050 回答
4

您是否尝试过使用 numpy 的recfunctions

import numpy.lib.recfunctions as rfn

它对结构化数组有一些非常有用的功能。

对于您的情况,我认为可以通过以下方式完成:

a = rfn.append_fields(a, 'USNG', np.empty(a.shape[0], dtype='|S100'), dtypes='|S100')

在这里测试,它工作。


合并数组

正如评论中提到的GMSL。可以使用 rfn.merge_arrays 来做到这一点,如下所示:

a = np.array([(1, [-112.01268501699997, 40.64249414272372]),
       (2, [-111.86145708699996, 40.4945008710162])], 
      dtype=[('i', '<i8'), ('loc', '<f8', (2,))])
a2 = np.full(a.shape[0], '', dtype=[('USNG', '|S100')])
a3 = rfn.merge_arrays((a, a2), flatten=True)

a3 将具有以下值:

array([(1, [-112.01268502,   40.64249414], b''),
       (2, [-111.86145709,   40.49450087], b'')],
      dtype=[('i', '<i8'), ('loc', '<f8', (2,)), ('USNG', 'S100')])
于 2020-06-15T20:46:57.400 回答
2
  1. recarraypandas.DataFrame或读取电流pandas.DataFrame.from_records
  2. 将新的数据列添加到数据框中
  3. 将数据框导出到recarraywithpandas.DataFrame.to_records
import pandas as pd
import numpy as np

# current recarray
data = np.rec.array([(1, list([-112.01268501699997, 40.64249414272372])), (2, list([-111.86145708699996, 40.4945008710162]))], dtype=[('i', '<i8'), ('loc', 'O')])

# create dataframe
df = pd.DataFrame(data)

# display(df)
   i                                       loc
0  1  [-112.01268501699997, 40.64249414272372]
1  2   [-111.86145708699996, 40.4945008710162]

# add new column
df['USNG'] = ['Note 1', 'Note 2']

# display(df)
   i                                       loc    USNG
0  1  [-112.01268501699997, 40.64249414272372]  Note 1
1  2   [-111.86145708699996, 40.4945008710162]  Note 2

# write the dataframe to recarray
data = df.to_records(index=False)

print(data)
[out]:
rec.array([(1, list([-112.01268501699997, 40.64249414272372]), 'Note 1'),
           (2, list([-111.86145708699996, 40.4945008710162]), 'Note 2')],
          dtype=[('i', '<i8'), ('loc', 'O'), ('USNG', 'O')])
于 2020-08-31T19:48:59.307 回答
1

问题正是:“关于为什么会发生这种情况的任何建议?”

从根本上说,这是一个错误--- 自 2012 年以来,它一直是 numpy 的公开票。

于 2015-03-03T11:13:31.860 回答
0

使用 200 万多个阵列,我立即注意到 Warren Weckesser 的解决方案和 Tonsic解决方案之间存在很大差异(非常感谢你们俩)

first_array
[out]
array([(1633046400299000, 1.34707, 1.34748),
       (1633046400309000, 1.347  , 1.34748),
       (1633046400923000, 1.347  , 1.34749), ...,
       (1635551693846000, 1.36931, 1.36958),
       (1635551693954000, 1.36925, 1.36952),
       (1635551697902000, 1.3692 , 1.36947)],
      dtype=[('timestamp', '<i8'), ('bid', '<f8'), ('ask', '<f8')])

second_array
[out]
array([('2021-10-01T00:00:00.299000',), ('2021-10-01T00:00:00.309000',),
       ('2021-10-01T00:00:00.923000',), ...,
       ('2021-10-29T23:54:53.846000',), ('2021-10-29T23:54:53.954000',),
       ('2021-10-29T23:54:57.902000',)], dtype=[('date_time', '<M8[us]')])

我明白了

%timeit rfn.merge_arrays((first_array, second_array), flatten=True)
[out]
13.8 s ± 1.11 s per loop (mean ± std. dev. of 7 runs, 1 loop each)

%timeit rfn.append_fields(first_array, 'date_time', second_array, dtypes='M8[us]').data
[out]
2.12 s ± 146 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

好多了(.data最后注意避免得到maskand fill_value

而使用类似的东西

def building_new(first_array, other_array):
    new_array = np.zeros(
        first_array.size, 
        dtype=[('timestamp', '<i8'), ('bid', '<f8'), ('ask', '<f8'), ('date_time', '<M8[us]')])
    new_array[['timestamp', 'bid', 'ask']] = first_array[['timestamp', 'bid', 'ask']]
    new_array['date_time'] = other_array
    return new_array

(请注意,在结构化数组中,每一行都是一个元组,因此 size 效果很好)

我明白了

%timeit building_new(first_array, second_array)
[out]
67.2 ms ± 3.56 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

三者的输出是一样的

[out]
array([(1633046400299000, 1.34707, 1.34748, '2021-10-01T00:00:00.299000'),
       (1633046400309000, 1.347  , 1.34748, '2021-10-01T00:00:00.309000'),
       (1633046400923000, 1.347  , 1.34749, '2021-10-01T00:00:00.923000'),
       ...,
       (1635551693846000, 1.36931, 1.36958, '2021-10-29T23:54:53.846000'),
       (1635551693954000, 1.36925, 1.36952, '2021-10-29T23:54:53.954000'),
       (1635551697902000, 1.3692 , 1.36947, '2021-10-29T23:54:57.902000')],
      dtype=[('timestamp', '<i8'), ('bid', '<f8'), ('ask', '<f8'), ('date_time', '<M8[us]')])

最后的想法:

创建新数组而不是recfunctions,第二个数组甚至不需要是结构化的

third_array
[out]
array(['2021-10-01T00:00:00.299000', '2021-10-01T00:00:00.309000',
       '2021-10-01T00:00:00.923000', ..., '2021-10-29T23:54:53.846000',
       '2021-10-29T23:54:53.954000', '2021-10-29T23:54:57.902000'],
      dtype='datetime64[us]')

%timeit building_new(first_array, third_array)
[out]
67 ms ± 1.58 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
于 2021-11-07T15:08:51.760 回答
0

Tonsic 提到了import numpy.lib.recfunctions as rfn. 在这种情况下,适合您的更简单的 recfunction 函数是rfn.merge_arrays()( docs )。

于 2020-10-22T12:04:25.663 回答