为了账号安全,请及时绑定邮箱和手机立即绑定

如何求每一行到最近满足条件的行的距离?

如何求每一行到最近满足条件的行的距离?

泛舟湖上清波郎朗 2023-12-05 15:49:10
import datetimeimport pandas as pdpd.DataFrame({'date': {0: datetime.date(2020, 8, 15),  1: datetime.date(2020, 8, 16),  2: datetime.date(2020, 8, 16),  3: datetime.date(2020, 8, 17),  4: datetime.date(2020, 8, 17),  5: datetime.date(2020, 8, 18),  6: datetime.date(2020, 8, 19),  7: datetime.date(2020, 8, 19)}, 'sign_change': {0: 0, 1: 0, 2: 0, 3: 1, 4: 1, 5: 0, 6: 1, 7: 1}, 'distance (desired_output)': {0: 2, 1: 1, 2: 1, 3: 0, 4: 0, 5: 1, 6: 0, 7: 0}})      date      sign_change         distance (desired_output)0  2020-08-15            0                          21  2020-08-16            0                          12  2020-08-16            0                          13  2020-08-17            1                          04  2020-08-17            1                          05  2020-08-18            0                          16  2020-08-19            1                          07  2020-08-19            1                          0对于每一行,我想找到到最近的行的距离(以天为单位),其中sign_change == 1。我已在上面的数据框中手动输入了所需的输出。
查看完整描述

2 回答

?
回首忆惘然

TA贡献1847条经验 获得超11个赞

我们来尝试一下广播:


s = df.sign_change!=1

offset = (np.abs(df.loc[s,'date'].values[None,:] - df.loc[~s,['date']].values).min(0)

            /pd.to_timedelta('1D')

         )


df['distance'] = 0

df.loc[s,'distance'] = offset

输出:


         date  sign_change  distance (desired_output)  distance

0  2020-08-15            0                          2       2.0

1  2020-08-16            0                          1       1.0

2  2020-08-16            0                          1       1.0

3  2020-08-17            1                          0       0.0

4  2020-08-17            1                          0       0.0

5  2020-08-18            0                          1       1.0

6  2020-08-19            1                          0       0.0

7  2020-08-19            1                          0       0.0


查看完整回答
反对 回复 2023-12-05
?
繁星coding

TA贡献1797条经验 获得超4个赞

您可以使用where,bfill()和ffill()。本质上,.where符号是1,您返回日期,否则返回NaN。从那里您可以bfill或向后填写该日期back到下一个日期1;您可以ffill将该日期填写forward到下一个日期1。fill然后取该日期和该日期的差值。最后,.fillna(0)是数据帧中的最后一个值。


解决方案#1 - 只期待最近的日期(有关整体最近的日期,请参阅解决方案#2):


df['distance (desired_output)'] = ((df['date'].where(df['sign_change'] == 1).bfill() 

                                    - df['date']).dt.days).fillna(0)

df

Out[1]: 

        date  sign_change  distance (desired_output)

0 2020-08-15            0                        2.0

1 2020-08-16            0                        1.0

2 2020-08-16            0                        1.0

3 2020-08-17            1                        0.0

4 2020-08-17            1                        0.0

5 2020-08-18            0                        1.0

6 2020-08-19            1                        0.0

7 2020-08-19            0                        0.0

解决方案#2(此解决方案ffill()与bfill()系列进行比较,并返回最接近日期的最小天数或天数,无论之前还是之后。


import datetime

import pandas as pd

df = pd.DataFrame({'date': {0: datetime.date(2020, 8, 15),

  1: datetime.date(2020, 8, 16),

  2: datetime.date(2020, 8, 16),

  3: datetime.date(2020, 8, 17),

  4: datetime.date(2020, 8, 17),

  5: datetime.date(2020, 8, 18),

  6: datetime.date(2020, 8, 19),

  7: datetime.date(2020, 8, 19),

  8: datetime.date(2020, 8, 20),

  9: datetime.date(2020, 8, 21)},

 'sign_change': {0: 0, 1: 0, 2: 0, 3: 1, 4: 1, 5: 0, 6: 1, 7: 1, 8: 0, 9: 0},

 'distance (desired_output)': {0: 2, 1: 1, 2: 1, 3: 0, 4: 0, 5: 1, 6: 0, 7: 0}})

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


s = (df['date'].where(df['sign_change'] == 1))

b = (s.bfill() - df['date']).dt.days

f = (s.ffill() - df['date']).dt.days.abs()

df['distance (desired_output)'] = np.where((b <= f) | (b.notnull()), b, f)

df

Out[2]: 

        date  sign_change  distance (desired_output)

0 2020-08-15            0                        2.0

1 2020-08-16            0                        1.0

2 2020-08-16            0                        1.0

3 2020-08-17            1                        0.0

4 2020-08-17            1                        0.0

5 2020-08-18            0                        1.0

6 2020-08-19            1                        0.0

7 2020-08-19            1                        0.0

8 2020-08-20            0                        1.0

9 2020-08-21            0                        2.0


查看完整回答
反对 回复 2023-12-05
  • 2 回答
  • 0 关注
  • 85 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信