与重叠列合并

时间:2014-06-17 09:06:09

标签: python-2.7 pandas

如果我有两个数据帧在同一时期内包含数据(虽然不一定是完全相同的日期),我想将它们合并在一起。可以认为数据看起来像这样:

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)

但这是一个痛苦,就像我有很多专栏的实际数据一样

1 个答案:

答案 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)