代码之家  ›  专栏  ›  技术社区  ›  Juan C

用三重索引填充数据框中的日期

  •  1
  • Juan C  · 技术社区  · 7 年前

    MultiIndexes 一直以来我都很难相处。问题是,我得到了以下数据帧:

     Date        Product    eCommerce   Sales
    12-10-2018      A           1        10
    12-12-2018      A           0        7
    12-13-2018      A           1        4
    12-15-2018      A           1        2
    12-15-2018      A           0        2
    12-11-2018      B           1        8
    12-13-2018      B           1        6
    

    所以我需要知道每个日期有没有电子商务的销售情况 . 我期望的结果是:

     Date        Product    eCommerce   Sales
    12-10-2018      A           1        10
    12-11-2018      A           1        0
    12-12-2018      A           1        0
    12-13-2018      A           1        4
    12-14-2018      A           1        0
    12-15-2018      A           1        2
    
    12-12-2018      A           0        7
    12-13-2018      A           0        0
    12-14-2018      A           0        0
    12-15-2018      A           0        2
    
    12-11-2018      B           1        8
    12-12-2018      B           1        0
    12-13-2018      B           1        6
    

    因此,在原始数据框中,产品A的电子商务销售缺少12-11和12-14,产品A的非电子商务销售缺少12-13和12-14,产品B的电子商务销售缺少12-12

    问题是,我通过一个非常低效的循环实现了我想要的目标,该循环运行大约需要25分钟:

    df_full= pd.DataFrame(columns=df.columns)
    for sku in df['Product'].unique():
    
        aux=df.loc[df['Product']==sku]
        dates= pd.DataFrame(pd.date_range(start=aux.Date.min(), end=aux.Date.max(),freq='D'),columns=['Date'])
    
        df3 = df.loc[df['id_prod']==sku].merge(dates,
                                                       how='outer',left_on='Date',
                                                       right_on='Date').sort_values(by='Date')
    
        df3.fillna(method='ffill',inplace=True)
        df_full= df_full.append(df3)
    

    我很有信心,我可以用矢量化的方式来做这件事,这应该需要更少的时间(我有2300个产品用于290个可能的日期)。你知道我怎样才能做到这一点吗?

    编辑:添加粗体文本,更好地解释问题

    1 回复  |  直到 7 年前
        1
  •  2
  •   ALollz    7 年前

    使用单个 DatetimeIndex 然后 groupby + resample.asfreq() ,(可以对数字列使用sum),因为日期范围取决于组。

    import pandas as pd
    
    df['Date'] = pd.to_datetime(df.Date)
    df = df.set_index('Date')
    
    df.groupby(['Product', 'eCommerce'], sort=False).Sales.resample('D').sum().reset_index()
    

    如果有许多列要用零填充,则:

    (df.groupby(['Product', 'eCommerce'], sort=False)
        .resample('D').sum()
        .drop(columns=['Product', 'eCommerce'])
        .reset_index())
    

    输出:

       Product  eCommerce       Date  Sales
    0        A          1 2018-12-10     10
    1        A          1 2018-12-11      0
    2        A          1 2018-12-12      0
    3        A          1 2018-12-13      4
    4        A          1 2018-12-14      0
    5        A          1 2018-12-15      2
    6        A          0 2018-12-12      7
    7        A          0 2018-12-13      0
    8        A          0 2018-12-14      0
    9        A          0 2018-12-15      2
    10       B          1 2018-12-11      8
    11       B          1 2018-12-12      0
    12       B          1 2018-12-13      6