如果我有两个数据帧在同一时期内包含数据(虽然不一定是完全相同的日期),我想将它们合并在一起。可以认为数据看起来像这样:
import datetime, random
import pandas as pd
dates = [datetime.date(2014, 1, 1), datetime.date(2014, 1, 2), datetime.date(2014, 1, 3)]
IDs = ['1001', '1002', '1003']
name = ['john', 'james', 'jim']
data1 = [random.randint(1, 100) for x in xrange(9)]
data2 = [random.randint(1, 100) for x in xrange(6)]
df1 = pd.DataFrame({'date' : dates * 3,
'ID' : IDs *3,
'name' : name * 3,
'data1': data1})
df2 = pd.DataFrame({'date' : dates[:2] * 3,
'ID' : IDs[:2] *3,
'name' : name[:2] * 3,
'data2':data2})
将对数据和ID列执行合并,如下所示:
merged = pd.merge(df1, df2, on = ['date', 'ID'], how = 'outer')
在这种情况下,显然我在结果数据帧中得到了name_x和name_y。如果有一种方法可以让结果数据帧只包含一个名称列,那么我想知道的是,列的值将是在name_x或name_y中找到的非NaN值。
另一种方式,是否有一种方法可以使用merge,这样在执行和外部合并时,在内部合并将“失败”的结果数据框中,保持非空的值?
这当然假设在内部合并成功的df1和df2中名称必须相同。我知道情况就是这样。
对于Jim的情况,我得到了这个输出:
ID data1 date name_x data2 name_y
18 1003 13 2014-03-01 jim NaN NaN
19 1003 98 2014-03-01 jim NaN NaN
20 1003 8 2014-03-01 jim NaN NaN
但我想要的是:
ID data1 date name data2
18 1003 13 2014-03-01 jim NaN
19 1003 98 2014-03-01 jim NaN
20 1003 8 2014-03-01 jim NaN
我知道合并后我可以很容易地做到这一点:
merged.name = merged.name_x.fillna(megred_y)
但这是一个痛苦,就像我有很多专栏的实际数据一样
答案 0 :(得分:0)
我认为没有内置任何内容可以合并以获得您所描述的行为。但是,正如你所指出的那样,事后并不应该处理那么大的交易。
如果您有很多列,是否可以通过迭代列来处理替换,如下所示?您可以将其包装在一个函数中并一步处理。
columns_to_fix = [c.rpartition('_x')[0] for c in merged.columns if c.endswith('_x')]
for c in columns_to_fix:
merged[c] = merged[c + '_x'].fillna(merged[c + '_y'])
merged = merged.drop([c + '_x', c + '_y'], axis=1)