我有一个起始数组:
[(1, [-112.01268501699997, 40.64249414272372])
(2, [-111.86145708699996, 40.4945008710162])]
其中第一列是int,第二列是带有浮点数的元组。我需要添加一个名为USNG的字符串列。
然后我创建一个结构化的numpy数组:
dtype = numpy.dtype([('USNG', '|S100')])
x = numpy.empty(array.shape, dtype=dtype)
我想将x numpy数组附加到现有数组以添加新列,以便我可以为每一行输出一些信息。当我执行以下操作时:
numpy.append(array, x, axis=1)# I've also tried vstack and hstack
我收到以下错误:
'TypeError: invalid type promotion'
有关为何发生这种情况的任何建议?
由于
答案 0 :(得分:7)
您必须创建一个包含新字段的新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')])
现在创建一个 new 结构化数组b
。我在这里使用zeros
,因此字符串字段将以值''
开头。您也可以使用empty
。然后字符串将包含垃圾,但如果您立即为它们分配值,则无关紧要。
In [88]: b = np.zeros(a.shape, dtype=new_dt)
将现有数据从a
复制到b
:
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')])
答案 1 :(得分:2)
您是否尝试过使用numpy的refunctions?
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')])
答案 2 :(得分:1)
recarray
添加列变得更加容易。
pandas.DataFrame
或pandas.DataFrame.from_records
读取当前的recarray
。pandas.DataFrame.to_records
将数据框导出到recarray
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')])
答案 3 :(得分:0)
问题恰恰是:&#34;有关为何发生这种情况的任何建议?&#34;
从根本上说,这是bug ---自2012年以来它一直是numpy的门票。
答案 4 :(得分:0)
Tonicic在df1 = df.groupby('ID',as_index=False,sort=False).last()
中提到了重新功能。在这种情况下,import numpy.lib.recfunctions as rfn
(docs)是最适合您的简化功能。