Заполнение всех столбцов даты и времени до определенной даты - PullRequest
2 голосов
/ 30 апреля 2019

У меня есть фрейм данных, представляющий ежедневную потребность разных продуктов и разных магазинов.

     SKU    Store    F  LeadTime    Date    Qty Value   Price   Level   
0   504777      1   135828  11  2018-01-22  1   3.99    3.99    45  
1   504777      1   135828  11  2018-01-23  0   0.00    0.00    45  
2   504777      1   135828  11  2018-01-24  3   11.97   3.99    42  
3   504777      1   135828  11  2018-01-25  1   3.99    3.99    41  
4   504777      1   135828  11  2018-01-26  0   0.00    0.00    41  


300 704777      2   135828  11  2018-01-22  1   4.99    3.99    45  
301 704777      2   135828  11  2018-01-23  0   0.00    0.00    47  
302 704777      2   135828  11  2018-01-24  4   12.97   3.99    48  
303 704777      2   135828  11  2018-01-25  1   3.99    3.99    49  

В этом примере я пытаюсь завершить набор данных до 2018-01-31, используя условия:

  • Поля: SKU, Store, F, LeadTime, Date, Level должны быть заполнены последним значением.

  • Поля: Qty, Value, Price должны быть заполнены 0.

Итак, мой ожидаемый результат должен быть таким:

     SKU    Store    F  LeadTime    Date    Qty Value   Price   Level   
0   504777      1   135828  11  2018-01-22  1   3.99    3.99    45  
1   504777      1   135828  11  2018-01-23  0   0.00    0.00    45  
2   504777      1   135828  11  2018-01-24  3   11.97   3.99    42  
3   504777      1   135828  11  2018-01-25  1   3.99    3.99    41  
4   504777      1   135828  11  2018-01-26  1   3.99    3.99   41  
5   504777      1   135828  11  2018-01-27  0   0.00    0.00    41  
6   504777      1   135828  11  2018-01-28  0   0.00    0.00    41  
7   504777      1   135828  11  2018-01-29  0   0.00    0.00    41                                                                
8   504777      1   135828  11  2018-01-30  0   0.00    0.00    41  
9   504777      1   135828  11  2018-01-31  0   0.00    0.00    41  

300 704777      2   135828  11  2018-01-22  1   4.99    3.99    45  
301 704777      2   135828  11  2018-01-23  0   0.00    0.00    47  
302 704777      2   135828  11  2018-01-24  4   12.97   3.99    48  
303 704777      2   135828  11  2018-01-25  1   3.99    3.99    49
304 704777      2   135828  11  2018-01-26  0    0       0       49  
305 704777      2   135828  11  2018-01-27  0    0       0      49
306 704777      2   135828  11  2018-01-28  0    0       0      49  
307 704777      2   135828  11  2018-01-29  0    0       0      49  
307 704777      2   135828  11  2018-01-30  0    0       0      49  
307 704777      2   135828  11  2018-01-31  0    0       0      49  

Я пробовал это:

df = df.set_index('Date').groupby(['SKU', 'Store']).date_range(end = '2018-01-31', freq='D').agg({
                                             'F':'last',
                                             'LeadTime':'last',
                                             'Price':0,
                                             'Value':0,
                                             'Qty':0,
                                             'Level':'last'}).reset_index()

Но это не правдаподход:

'DataFrameGroupBy' object has no attribute 'date_range'

PS: каждый продукт имеет различную начальную дату

Ответы [ 2 ]

1 голос
/ 30 апреля 2019

Я бы предложил вам попробовать reindex в каждой группе.Затем создайте список для хранения каждой группы и создайте DataFrame из этого списка.

df['Date'] = pd.to_datetime(df['Date'])

dfs = []
for _, d in df.groupby(['SKU', 'Store']):

    start_date = d.Date.iloc[0]
    end_date = start_date + pd.offsets.MonthEnd()

    d.set_index('Date', inplace=True)
    d = d.reindex(pd.date_range(start_date, end_date))
    d.fillna

    dfs.append(d)

new_df = pd.concat(dfs)

new_df

                 SKU  Store         F  LeadTime  Qty  Value  Price  Level
2018-01-22  504777.0    1.0  135828.0      11.0  1.0   3.99   3.99   45.0
2018-01-23  504777.0    1.0  135828.0      11.0  0.0   0.00   0.00   45.0
2018-01-24  504777.0    1.0  135828.0      11.0  3.0  11.97   3.99   42.0
2018-01-25  504777.0    1.0  135828.0      11.0  1.0   3.99   3.99   41.0
2018-01-26  504777.0    1.0  135828.0      11.0  0.0   0.00   0.00   41.0
2018-01-27       NaN    NaN       NaN       NaN  NaN    NaN    NaN    NaN
2018-01-28       NaN    NaN       NaN       NaN  NaN    NaN    NaN    NaN
2018-01-29       NaN    NaN       NaN       NaN  NaN    NaN    NaN    NaN
2018-01-30       NaN    NaN       NaN       NaN  NaN    NaN    NaN    NaN
2018-01-31       NaN    NaN       NaN       NaN  NaN    NaN    NaN    NaN
2018-01-22  704777.0    2.0  135828.0      11.0  1.0   4.99   3.99   45.0
2018-01-23  704777.0    2.0  135828.0      11.0  0.0   0.00   0.00   47.0
2018-01-24  704777.0    2.0  135828.0      11.0  4.0  12.97   3.99   48.0
2018-01-25  704777.0    2.0  135828.0      11.0  1.0   3.99   3.99   49.0
2018-01-26       NaN    NaN       NaN       NaN  NaN    NaN    NaN    NaN
2018-01-27       NaN    NaN       NaN       NaN  NaN    NaN    NaN    NaN
2018-01-28       NaN    NaN       NaN       NaN  NaN    NaN    NaN    NaN
2018-01-29       NaN    NaN       NaN       NaN  NaN    NaN    NaN    NaN
2018-01-30       NaN    NaN       NaN       NaN  NaN    NaN    NaN    NaN
2018-01-31       NaN    NaN       NaN       NaN  NaN    NaN    NaN    NaN

Затем используйте ffill для заполнения NaN.

new_df = pd.concat(dfs)
new_df[['Price', 'Qty', 'Value']] = new_df[['Price', 'Qty', 'Value']].fillna(0)
new_df.ffill(inplace=True)
new_df
Out[17]: 
                 SKU  Store         F  LeadTime  Qty  Value  Price  Level
2018-01-22  504777.0    1.0  135828.0      11.0  1.0   3.99   3.99   45.0
2018-01-23  504777.0    1.0  135828.0      11.0  0.0   0.00   0.00   45.0
2018-01-24  504777.0    1.0  135828.0      11.0  3.0  11.97   3.99   42.0
2018-01-25  504777.0    1.0  135828.0      11.0  1.0   3.99   3.99   41.0
2018-01-26  504777.0    1.0  135828.0      11.0  0.0   0.00   0.00   41.0
2018-01-27  504777.0    1.0  135828.0      11.0  0.0   0.00   0.00   41.0
2018-01-28  504777.0    1.0  135828.0      11.0  0.0   0.00   0.00   41.0
2018-01-29  504777.0    1.0  135828.0      11.0  0.0   0.00   0.00   41.0
2018-01-30  504777.0    1.0  135828.0      11.0  0.0   0.00   0.00   41.0
2018-01-31  504777.0    1.0  135828.0      11.0  0.0   0.00   0.00   41.0
2018-01-22  704777.0    2.0  135828.0      11.0  1.0   4.99   3.99   45.0
2018-01-23  704777.0    2.0  135828.0      11.0  0.0   0.00   0.00   47.0
2018-01-24  704777.0    2.0  135828.0      11.0  4.0  12.97   3.99   48.0
2018-01-25  704777.0    2.0  135828.0      11.0  1.0   3.99   3.99   49.0
2018-01-26  704777.0    2.0  135828.0      11.0  0.0   0.00   0.00   49.0
2018-01-27  704777.0    2.0  135828.0      11.0  0.0   0.00   0.00   49.0
2018-01-28  704777.0    2.0  135828.0      11.0  0.0   0.00   0.00   49.0
2018-01-29  704777.0    2.0  135828.0      11.0  0.0   0.00   0.00   49.0
2018-01-30  704777.0    2.0  135828.0      11.0  0.0   0.00   0.00   49.0
2018-01-31  704777.0    2.0  135828.0      11.0  0.0   0.00   0.00   49.0
1 голос
/ 30 апреля 2019

Первая группа в SKU и Store.

В то же время вы можете создать date_range с start как максимальное значение для вас df и end как 2018-01-31.

Примечание Я использую здесь понимание списка для выигрыша с точки зрения скорости.

Тогда fillna столбцыс 0 по мере необходимости.

Наконец concat всех групповых кадров данных и используйте forwardfill (ffill):

dfs = [pd.concat([d, pd.DataFrame({'Date':pd.date_range(start=d['Date'].max(), end=pd.Timestamp(2018,1,31))})], ignore_index=True, sort=False) for _, d in df.groupby(['SKU', 'Store'])]

for df in dfs:
    df[['Qty', 'Value', 'Price']] = df[['Qty', 'Value', 'Price']].fillna(0)

df = pd.concat(dfs, ignore_index=True, sort=False).ffill()

print(df)
         SKU  Store         F  LeadTime       Date  Qty  Value  Price  Level
0   504777.0    1.0  135828.0      11.0 2018-01-22  1.0   3.99   3.99   45.0
1   504777.0    1.0  135828.0      11.0 2018-01-23  0.0   0.00   0.00   45.0
2   504777.0    1.0  135828.0      11.0 2018-01-24  3.0  11.97   3.99   42.0
3   504777.0    1.0  135828.0      11.0 2018-01-25  1.0   3.99   3.99   41.0
4   504777.0    1.0  135828.0      11.0 2018-01-26  0.0   0.00   0.00   41.0
5   504777.0    1.0  135828.0      11.0 2018-01-26  0.0   0.00   0.00   41.0
6   504777.0    1.0  135828.0      11.0 2018-01-27  0.0   0.00   0.00   41.0
7   504777.0    1.0  135828.0      11.0 2018-01-28  0.0   0.00   0.00   41.0
8   504777.0    1.0  135828.0      11.0 2018-01-29  0.0   0.00   0.00   41.0
9   504777.0    1.0  135828.0      11.0 2018-01-30  0.0   0.00   0.00   41.0
10  504777.0    1.0  135828.0      11.0 2018-01-31  0.0   0.00   0.00   41.0
11  704777.0    2.0  135828.0      11.0 2018-01-22  1.0   4.99   3.99   45.0
12  704777.0    2.0  135828.0      11.0 2018-01-23  0.0   0.00   0.00   47.0
13  704777.0    2.0  135828.0      11.0 2018-01-24  4.0  12.97   3.99   48.0
14  704777.0    2.0  135828.0      11.0 2018-01-25  1.0   3.99   3.99   49.0
15  704777.0    2.0  135828.0      11.0 2018-01-25  0.0   0.00   0.00   49.0
16  704777.0    2.0  135828.0      11.0 2018-01-26  0.0   0.00   0.00   49.0
17  704777.0    2.0  135828.0      11.0 2018-01-27  0.0   0.00   0.00   49.0
18  704777.0    2.0  135828.0      11.0 2018-01-28  0.0   0.00   0.00   49.0
19  704777.0    2.0  135828.0      11.0 2018-01-29  0.0   0.00   0.00   49.0
20  704777.0    2.0  135828.0      11.0 2018-01-30  0.0   0.00   0.00   49.0
21  704777.0    2.0  135828.0      11.0 2018-01-31  0.0   0.00   0.00   49.0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...