J'ai un df comme ci-dessous:
timestamp President 1992-01-01 B Clinton 1992-01-02 B Clinton ... 2000-01-01 G Bush ...
Je veux créer un autre df, quelque chose comme ça
President Start Date End Date B Clinton 1992-01-01 1999-12-31 G Bush 2000-01-01 2007-12-31 B Obama 2008-01-01 2015-12-31 D Trump 2016-01-01 2019-12-31 # not too far away!!
En gros, je veux créer une trame de données dont son index est horodaté, puis son contenu est sélectionné en fonction de la condition des deux colonnes d'un autre df.
Je pense qu'il y a un moyen au sein des pandas de le faire, mais je ne le suis pas sûr comment. J'ai essayé d'utiliser np.piecewise mais il semble que générer les conditions sera très difficile pour moi. Comment pourrais-je faire cela?
3 Réponses :
Vous pouvez utiliser pd.date_range pour créer une plage de dates à partir des valeurs de début et de fin. Assurez-vous que les dates de début et de fin sont au format datetime.
s = df.set_index('President').apply(lambda x: pd.Series(pd.date_range(x['Start Date'], x['End Date'])), axis = 1).stack().reset_index(1, drop = True)
new_df = pd.DataFrame(s.index.values, index=s, columns = ['President'] )
President
1992-01-01 B Clinton
1992-01-02 B Clinton
1992-01-03 B Clinton
1992-01-04 B Clinton
1992-01-05 B Clinton
1992-01-06 B Clinton
1992-01-07 B Clinton
1992-01-08 B Clinton
1992-01-09 B Clinton
Vous ne voudrez peut-être pas utiliser apply. :-) stackoverflow.com/questions/54432583/...
Ceci est un autre problème de désemboîtement
def unnesting(df, explode):
idx=df.index.repeat(df[explode[0]].str.len())
df1=pd.concat([pd.DataFrame({x:np.concatenate(df[x].values)} )for x in explode],axis=1)
df1.index=idx
return df1.join(df.drop(explode,1),how='left')
Pour info, j'ai collé la fonction ici
df['New']=[pd.date_range(x,y).tolist() for x , y in zip (df.StartDate,df.EndDate)] unnesting(df,['New'])
Vous pourriez peut-être utiliser un PeriodIndex au lieu d'un DatetimeIndex car vous avez affaire à des intervalles de temps régulièrement espacés, c'est-à-dire des années.
# create a list of PeriodIndex objects with annual frequency
p_idxs = [pd.period_range(start, end, freq='A') for idx, (start, end) in df[['Start Date', 'End Date']].iterrows()]
# for each PeriodIndex create a DataFrame where
# the number of president instances matches the length of the PeriodIndex object
df_list = []
for pres, p_idx in zip(df['President'].tolist(), p_idxs):
df_ = pd.DataFrame(data=len(p_idx)*[pres], index=p_idx)
df_list.append(df_)
# concatenate everything to get the desired output
df_desired = pd.concat(df_list, axis=0)