Как сделать сложный отбор в пандах? - PullRequest
0 голосов
/ 22 февраля 2019

У меня есть df, как показано ниже:

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!!

Я хочу создать еще один df, что-то вроде этого

timestamp   President
1992-01-01  B Clinton
1992-01-02  B Clinton
...
2000-01-01  G Bush
...

В основном я хочу создать фрейм данных, индекс которого - времяштамп, а затем его содержимое выбирается на основе условия в двух столбцах другого df.

Я чувствую, что в пандах есть способ сделать это, но я не уверен, как это сделать.Я пытался использовать np.piecewise, но, кажется, создание условий будет для меня очень трудным.Как я мог это сделать?

Ответы [ 3 ]

0 голосов
/ 22 февраля 2019

Это еще одна unnesting проблема

df['New']=[pd.date_range(x,y).tolist() for x , y in zip (df.StartDate,df.EndDate)]

unnesting(df,['New'])

К вашему сведению Я вставил сюда функцию

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')
0 голосов
/ 22 февраля 2019

Возможно, вы могли бы использовать PeriodIndex вместо DatetimeIndex, потому что вы имеете дело с регулярно разнесенными интервалами времени, т. Е. Годами.

# 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)
0 голосов
/ 22 февраля 2019

Вы можете использовать pd.date_range для создания диапазона дат из начальных и конечных значений.Убедитесь, что даты начала и окончания указаны в формате 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...