У меня есть пандас, как это,

    id  d1  d2
0   1   2016-12-15  2017-02-08
1   2   2017-04-28  2017-07-20
2   3   2017-07-28  2017-10-19
3   4   2018-02-20  2019-01-21
4   5   2019-03-19  2019-06-10
5   1   2019-05-24  2019-05-30
6   2   2019-06-04  2019-07-22

Я хочу проверить, больше ли d2, чем следующий d1, если это так, я хочу установить этот d2 на следующий d1 - 1.

Я могу выяснить, где я хочу изменить дату с помощью этого кода,

x['d2'].gt(x['d1'].shift(-1))

Я не уверен, как действовать эффективно после этого.

Результат, который я ищу, таков,

    id  d1  d2
0   1   2016-12-15  2017-02-08
1   2   2017-04-28  2017-07-20
2   3   2017-07-28  2017-10-19
3   4   2018-02-20  2019-01-21
4   5   2019-03-19  2019-05-23
5   1   2019-05-24  2019-05-30
6   2   2019-06-04  2019-07-22

Как я могу сделать это в пандах без петель.?

В настоящее время я использую apply, как это для решения этой проблемы,

x.apply(lambda x : x['d1_shifted'] - pd.Timedelta(days=1) if x['d2'] > x['d1_shifted'] else x['d2'], axis=1)
1
Sreeram TP 16 Авг 2019 в 21:55

2 ответа

Лучший ответ

Пытаться :

c=df.d2.gt(df.d1.shift(-1))
df=df.assign(d2=np.where(c,df.d1.shift(-1)-pd.Timedelta(1,unit='d'),df.d2))
print(df)

   id         d1         d2
0   1 2016-12-15 2017-02-08
1   2 2017-04-28 2017-07-20
2   3 2017-07-28 2017-10-19
3   4 2018-02-20 2019-01-21
4   5 2019-03-19 2019-05-23
5   1 2019-05-24 2019-05-30
6   2 2019-06-04 2019-07-22
2
anky_91 16 Авг 2019 в 19:07

Другой способ - использовать прямое назначение из .loc и pd.DateOffset следующим образом

m = df.d2.gt(df.d1.shift(-1))
df.loc[m, 'd2'] = df.shift(-1).loc[m, 'd1'] - pd.DateOffset(1)

Out[947]:
   id         d1         d2
0  1  2016-12-15 2017-02-08
1  2  2017-04-28 2017-07-20
2  3  2017-07-28 2017-10-19
3  4  2018-02-20 2019-01-21
4  5  2019-03-19 2019-05-23
5  1  2019-05-24 2019-05-30
6  2  2019-06-04 2019-07-22
1
Andy L. 16 Авг 2019 в 19:46