【问题标题】:Merge DataFrame based on groups基于组合并DataFrame
【发布时间】:2018-02-05 21:49:07
【问题描述】:

我正在尝试将两个不同的 DataFrame 合并为一个排序的。

我的输入文件可以这样表示:

import pandas as pd
rng = pd.date_range('05:37', periods= 5, freq='5Min')
df1 = pd.DataFrame({'key':['A','A','A','B','B'],'bus_code':['601','602','605','602','606'], 'time': rng})
df2 = pd.DataFrame({'bus_code':['601','602','603','604','605'],'distance':['0.1','0.5','1.2','1.9','2.5']})
print(df1)
print(df2) 

列中的key代表不同的组,所以对于每个组,我想将它们与路由距离完全连接在一起,结果应该是这样的:

     bus_code key   time      distance
0      601    A   05:37:00      0.1
1      602    A   05:42:00      0.5
2      603    A        NaT      1.2
3      604    A        NaT      1.9
4      605    A   05:47:00      2.5

0      601    B        NaT      0.1
1      602    B   05:52:00      0.5   
2      603    B        NaT      1.2
3      604    B        NaT      1.9
4      605    B        NaT      2.5
5      606    B   05:57:00      NaN

以下是我为实现这一目标所做的工作:

new_df = pd.DataFrame()
for name, group in df1.groupby('key'):
#   print(group)
    new_df = new_df.append(pd.merge(group, df2, left_on='bus_code', right_on='bus_code', how='outer').sort_values('distance'))

print(new_df)

但结果漏掉了一些key值:

     bus_code key    time    distance
0      601    A   05:37:00      0.1
1      602    A   05:42:00      0.5
2      605    A   05:47:00      2.5
3      603  NaN        NaT      1.2
4      604  NaN        NaT      1.9
0      602    B   05:52:00      0.5
1      601  NaN        NaT      0.1
2      603  NaN        NaT      1.2
3      604  NaN        NaT      1.9
4      605  NaN        NaT      2.5
5      606    B   05:57:00      NaN

所以这是我的问题,我怎样才能加回缺少的key 值?

【问题讨论】:

    标签: python pandas dataframe merge group-by


    【解决方案1】:

    为了解决您最初的问题,您可以使用pd.Series.ffill

    df.key.ffill(inplace=True)
    print(df)
    
       bus_code key      time  distance
    0       601   A  05:37:00       0.1
    1       602   A  05:42:00       0.5
    2       605   A  05:47:00       2.5
    3       603   A       NaT       1.2
    4       604   A       NaT       1.9
    0       602   B  05:52:00       0.5
    1       601   B       NaT       0.1
    2       603   B       NaT       1.2
    3       604   B       NaT       1.9
    4       605   B       NaT       2.5
    5       606   B  05:57:00       NaN
    

    作为替代方法,您可以改用groupbyapply 操作:

    g = df1.groupby('key', as_index=False)\
                  .apply(lambda x: x.merge(df2, on='bus_code', how='outer')\
                  .sort_values(['bus_code', 'key'])\
                  .set_index(['bus_code', 'time', 'distance']).bfill().reset_index())
           .reset_index(drop=1)   
    
    print(g)
    
       bus_code                time distance key
    0       601 2017-08-28 05:37:00      0.1   A
    1       602 2017-08-28 05:42:00      0.5   A
    2       603                 NaT      1.2   A
    3       604                 NaT      1.9   A
    4       605 2017-08-28 05:47:00      2.5   A
    5       601                 NaT      0.1   B
    6       602 2017-08-28 05:52:00      0.5   B
    7       603                 NaT      1.2   B
    8       604                 NaT      1.9   B
    9       605                 NaT      2.5   B
    10      606 2017-08-28 05:57:00      NaN   B 
    

    【讨论】:

    • ffill() 操作错误填写了总线 601 的密钥 A
    • @cᴏʟᴅsᴘᴇᴇᴅ 谢谢,按它们的排序顺序填充值非常棒,但是如果 df1 更改为 'key' : ['A','A','A'], 'bus_code' : ['601','602','604'],那么它会错误地填充总线 605 的键 A
    • @Ethan 已编辑,我现在在每个组内进行 bfill。
    猜你喜欢
    • 2016-11-22
    • 2023-02-14
    • 1970-01-01
    • 1970-01-01
    • 2020-12-25
    • 1970-01-01
    • 1970-01-01
    • 2014-02-17
    • 1970-01-01
    相关资源
    最近更新 更多