首页 > 解决方案 > Pandas concat/merge Dataframes 用列中的最后一个填充缺失值

问题描述

我想将两个熊猫数据框的数据聚合为一个,其中该列total需要用以前的现有值回填,这是我的代码:

import pandas as pd

df1 = pd.DataFrame({
    'date': ['2020-01-01', '2020-01-02', '2020-01-03', '2020-01-05'],
    'day_count': [1, 1, 1, 1],
    'total': [1, 2, 3, 4]})

df2 = pd.DataFrame({
    'date': ['2020-01-02', '2020-01-03', '2020-01-04'],
    'day_count': [2, 2, 2],
    'total': [2, 4, 6]})

# set "date" as index and convert to datetime for later resampling
df1.index = df1['date']
df1.index = pd.to_datetime(df1.index)
df2.index = df2['date']
df2.index = pd.to_datetime(df2.index)

现在我需要将我的两个数据帧重新采样到某个频率,假设daily我会这样做:

df1 = df1.resample('D').agg({'day_count': 'sum', 'total': 'last'})
df2 = df2.resample('D').agg({'day_count': 'sum', 'total': 'last'})

数据框现在看起来像:

In [20]: df1
Out[20]:
            day_count  total
date
2020-01-01          1    1.0
2020-01-02          1    2.0
2020-01-03          1    3.0
2020-01-04          0    NaN
2020-01-05          1    4.0


In [22]: df2
Out[22]:
            day_count  total
date
2020-01-02          2      2
2020-01-03          2      4
2020-01-04          2      6

现在我需要合并两者,但请注意,总计有一些NaN值,我需要回填以前存在的值,所以我这样做:

df1['total'] = df1['total'].fillna(method='ffill').astype(int)
df2['total'] = df2['total'].fillna(method='ffill').astype(int)

现在 df1 看起来像:

In [25]: df1
Out[25]:
            day_count  total
date
2020-01-01          1      1
2020-01-02          1      2
2020-01-03          1      3
2020-01-04          0      3
2020-01-05          1      4

所以现在我已经准备好合并两个数据框了,我想,所以我将它们连接起来:

final_df = pd.concat([df1, df1]).fillna(method='ffill').groupby(["date"], as_index=True).sum()

In [31]: final_df
Out[31]:
            day_count  total
date
2020-01-01          1      1
2020-01-02          3      4
2020-01-03          3      7
2020-01-04          2      9
2020-01-05          1      4

我有正确的聚合,可以day_count简单地将两个 DF 的同一日期的内容相加,但因为total我没有得到我期望的结果,即得到:

In [31]: final_df
Out[31]:
            day_count  total
date
2020-01-01          1      1
2020-01-02          3      4
2020-01-03          3      7
2020-01-04          2      9
2020-01-05          1      10  --> this value I miss

当然我做错了什么,我觉得也许有更简单的方法可以做到这一点,谢谢!

标签: pythonpandasdataframe

解决方案


将它们水平连接并沿列分组:

pd.concat([df1,df2], axis=1).ffill().groupby(level=0, axis=1).sum()

也就是说,您也可以绕过个人fillnagroupby

# these are not needed
# df1['total'] = df1['total'].fillna(method='ffill').astype(int)
# df2['total'] = df2['total'].fillna(method='ffill').astype(int)
pd.concat([df1,df2],axis=1).ffill().sum(level=0, axis=1)

输出:

            day_added  total
date                        
2020-01-01        1.0    1.0
2020-01-02        3.0    4.0
2020-01-03        3.0    7.0
2020-01-04        2.0    9.0
2020-01-05        3.0   10.0

推荐阅读