2017-01-09 97 views
3

我有大約運行的各種促銷活動和他們的開始日期,結束日期的信息的推廣說明數據集:數據操作開始日期結束日期蟒蛇熊貓

promo  item  start_date  end_date 

Buy1-get 1  A  2015-01-08 2015-01-12 

Buy1-get 1  A  2015-02-16 2015-02-20 

Buy1-40% off B  2016-05-08  2016-05-09 

現在我要組織我的數據以供後續分析,使得我只有單一的可變日期和促銷信息。

date   item  Promo 

2015-01-08  A   Buy1-get 1 

2015-01-09  A   Buy1-get 1 
2015-01-10  A   ...... 
2015-01-11  .... 
2015-01-12 

2015-02-16  A   Buy1-get 1 
2015-02-17  A   Buy1-get 1 
2015-02-18  ....  ....... 
2015-02-19  ..... 

.......... 
2016-05-09  B   Buy1-40% off 

任何幫助將非常感激。

回答

3

可以使用concat通過date_rangeitertuples創建的所有Series秒,然後joinpromoitem

df1 = pd.concat([pd.Series(r.Index, 
          pd.date_range(r.start_date,r.end_date)) for r in df.itertuples()]) 
     .reset_index() 
df1.columns = ['date','idx'] 
df1 = df1.set_index('idx') 
df1 = df1.join(df[['item','promo']]).reset_index(drop=True) 
print (df1) 
     date item   promo 
0 2015-01-08 A Buy1-get 1 
1 2015-01-09 A Buy1-get 1 
2 2015-01-10 A Buy1-get 1 
3 2015-01-11 A Buy1-get 1 
4 2015-01-12 A Buy1-get 1 
5 2015-02-16 A Buy1-get 1 
6 2015-02-17 A Buy1-get 1 
7 2015-02-18 A Buy1-get 1 
8 2015-02-19 A Buy1-get 1 
9 2015-02-20 A Buy1-get 1 
10 2016-05-08 B Buy1-40% off 
11 2016-05-09 B Buy1-40% off 

meltgroupby with resample另一種解決方案:

df1 = df.reset_index().rename(columns={'index':'idx'}) 
df1 = pd.melt(df1, id_vars='idx', value_vars=['start_date','end_date'], value_name='date') 
     .set_index('date') 
df1 = df1.groupby('idx') 
     .resample('d') 
     .ffill() 
     .reset_index(level=1) 
     .drop(['idx','variable'], axis=1) 
df1 = df1.join(df[['item','promo']]).reset_index(drop=True) 
print (df1) 
     date item   promo 
0 2015-01-08 A Buy1-get 1 
1 2015-01-09 A Buy1-get 1 
2 2015-01-10 A Buy1-get 1 
3 2015-01-11 A Buy1-get 1 
4 2015-01-12 A Buy1-get 1 
5 2015-02-16 A Buy1-get 1 
6 2015-02-17 A Buy1-get 1 
7 2015-02-18 A Buy1-get 1 
8 2015-02-19 A Buy1-get 1 
9 2015-02-20 A Buy1-get 1 
10 2016-05-08 B Buy1-40% off 
11 2016-05-09 B Buy1-40% off 
1

您可以讓非日期列採用索引軸,因爲它們在任何更改m的方向上都會發生變化適用於日期列。這在分組操作中會很方便。

指定append=True有助於跟蹤哪些原DF之前所擁有的索引。 stack它們從而使START_DATEEND_DATE跌破彼此。

mi_ser = df.set_index(['promo', 'item'], append=True).stack() 
grouper = mi_df.index.get_level_values(0) 

構造一個新的Series有它的價值和指數一樣存在於我們之前的多指數系列對象中的值。

執行groupby w.r.t第一個索引級別並根據每日頻率重新採樣這些值,並選擇與datetime值兼容的任何形式的聚合函數。 [在此,first選擇]

s = pd.Series(mi_ser.values, mi_ser.values).groupby(grouper).resample('D').first() 
idx, val = s.index.get_level_values(0), s.index.get_level_values(1) 

同樣,構造新的數據幀具有它是如下面所定義的值和索引這個時候。由於索引是對齊的,我們可以沿着它們的兩個數據幀。

pd.DataFrame(val, idx, ['date']).join(df[['item', 'promo']]).reset_index(drop=True) 

enter image description here

1

不介意我。我只是想numpy -fy這個問題/答案

day = int(60 * 60 * 24 * 1e9) 

sd = df.start_date.values 
ed = df.end_date.values 
dd = ed - sd 
ds = (dd/day).astype(int) + 1 

sdays = ds.sum() 
cdays = ds.cumsum() 
rng = np.arange(sdays) 
slc = np.roll(cdays % sdays, 1) 
add = rng - rng[slc].repeat(ds) 

d1 = pd.DataFrame(dict(
     promo=df.promo.values.repeat(ds), 
     item=df.item.values.repeat(ds), 
    ), pd.Index(sd.repeat(ds) + add * day, name='date')) 

print(d1) 

      item   promo 
date       
2015-01-08 A Buy1-get 1 
2015-01-09 A Buy1-get 1 
2015-01-10 A Buy1-get 1 
2015-01-11 A Buy1-get 1 
2015-01-12 A Buy1-get 1 
2015-02-16 A Buy1-get 1 
2015-02-17 A Buy1-get 1 
2015-02-18 A Buy1-get 1 
2015-02-19 A Buy1-get 1 
2015-02-20 A Buy1-get 1 
2016-05-08 B Buy1-40% off 
2016-05-09 B Buy1-40% off 
相關問題