【问题标题】:Pandas: Filling data for missing dates熊猫:填写缺失日期的数据
【发布时间】:2019-04-09 10:03:15
【问题描述】:

假设我有下表:

ProdID  Date        Val1 Val2 Val3
Prod1   4/1/2019    1    3    4
Prod1   4/3/2019    2    3    54
Prod1   4/4/2019    3    4    54
Prod2   4/1/2019    1    3    3
Prod2   4/2/2019    1    3    4
Prod2   4/3/2019    2    4    4
Prod2   4/4/2019    2    5    3

Prod2 条目已正确填充,因为我们已经获得了从 4/1/20194/4/2019 的数据。

Prod1 缺少 1 个日期 - 4/2/2019

我想查找所有 ProdID 的缺失日期,并使用从上一个条目的最后一个条目复制的数据填写 Val1-3。例如,我想将数据从4/1/2019复制到4/2/2019

ProdID  Date        Val1 Val2 Val3
Prod1   4/1/2019    1    3    4
Prod1   4/2/2019    1    3    4
Prod1   4/3/2019    2    3    54
Prod1   4/4/2019    3    4    54
Prod2   4/1/2019    1    3    3
Prod2   4/2/2019    1    3    4
Prod2   4/3/2019    2    4    4
Prod2   4/4/2019    2    5    3

【问题讨论】:

    标签: python pandas missing-data


    【解决方案1】:

    首先通过to_datetime 将列转换为datetimes,然后通过DataFrame.set_index 创建DatetimeIndex 并使用DataFrame.asfreq 调用GroupBy.apply - 也可以指定向前或向后填充缺失值的方法:

    df['Date'] = pd.to_datetime(df['Date'])
    
    df1 = (df.set_index('Date')
             .groupby('ProdID')
             .apply(lambda x: x.asfreq('D', method='ffill'))
             .reset_index(level=0, drop=True)
             .reset_index()
             .reindex(df.columns, axis=1))
    
    print (df1)
      ProdID       Date  Val1  Val2  Val3
    0  Prod1 2019-04-01     1     3     4
    1  Prod1 2019-04-02     1     3     4
    2  Prod1 2019-04-03     2     3    54
    3  Prod1 2019-04-04     3     4    54
    4  Prod2 2019-04-01     1     3     3
    5  Prod2 2019-04-02     1     3     4
    6  Prod2 2019-04-03     2     4     4
    7  Prod2 2019-04-04     2     5     3
    

    另一种解决方案是通过productDataFrame.merge 使用左连接创建产品和datetimes 的所有组合,最后通过ffill 前向填充缺失值:

    dates = pd.date_range(start=df['Date'].min(), end=df['Date'].max())
    prods = df.ProdID.unique()
    
    from  itertools import product
    df1 = pd.DataFrame(list(product(prods, dates)), columns=['ProdID', 'Date'])
    print (df1)
      ProdID       Date
    0  Prod1 2019-04-01
    1  Prod1 2019-04-02
    2  Prod1 2019-04-03
    3  Prod1 2019-04-04
    4  Prod2 2019-04-01
    5  Prod2 2019-04-02
    6  Prod2 2019-04-03
    7  Prod2 2019-04-04
    
    df = df1.merge(df, how='left').ffill()
    print (df)
      ProdID       Date  Val1  Val2  Val3
    0  Prod1 2019-04-01   1.0   3.0   4.0
    1  Prod1 2019-04-02   1.0   3.0   4.0
    2  Prod1 2019-04-03   2.0   3.0  54.0
    3  Prod1 2019-04-04   3.0   4.0  54.0
    4  Prod2 2019-04-01   1.0   3.0   3.0
    5  Prod2 2019-04-02   1.0   3.0   4.0
    6  Prod2 2019-04-03   2.0   4.0   4.0
    7  Prod2 2019-04-04   2.0   5.0   3.0
    

    【讨论】:

    • 谢谢。它返回以下错误:“ValueError:NaTType 不支持时间”
    • @MarekK - 你的熊猫版本是什么?
    • 版本:0.23.4
    • @MarekK - 正在寻找另一种解决方案,请稍等。
    • 我知道问题出在哪里。看起来我在输入 csv 文件中的日期格式不一致。我需要先修复它。
    【解决方案2】:

    您也可以像这样使用pandas.MultiIndex.from_productDataFrame.reindexDataFrame.ffill

    df['Date'] = pd.to_datetime(df['Date'])
    dates = pd.date_range(start=df.Date.min(), end=df.Date.max(), freq='1D')
    
    idx = pd.MultiIndex.from_product([df.ProdID.unique(), dates], names=['ProdID', 'Date'])
    
    df.set_index(['ProdID', 'Date']).reindex(idx).ffill().reset_index()
    

    [输出]

      ProdID       Date  Val1  Val2  Val3
    0  Prod1 2019-04-01   1.0   3.0   4.0
    1  Prod1 2019-04-02   1.0   3.0   4.0
    2  Prod1 2019-04-03   2.0   3.0  54.0
    3  Prod1 2019-04-04   3.0   4.0  54.0
    4  Prod2 2019-04-01   1.0   3.0   3.0
    5  Prod2 2019-04-02   1.0   3.0   4.0
    6  Prod2 2019-04-03   2.0   4.0   4.0
    7  Prod2 2019-04-04   2.0   5.0   3.0
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-08-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-14
      • 1970-01-01
      • 2017-12-12
      • 1970-01-01
      相关资源
      最近更新 更多