[英]Find row with nearest value in a subset of a pandas DataFrame
我有以下结构的 dataframe:
import pandas as pd
df = pd.DataFrame({'x': [1,5,8,103,105,112],
'date': pd.DatetimeIndex(('2022-02-01', '2022-02-03', '2022-02-06',
'2022-02-05', '2022-02-05', '2022-02-07'))})
x dt
0 1 2022-02-01
1 5 2022-02-03
2 8 2022-02-06
3 103 2022-02-05
4 105 2022-02-05
5 112 2022-02-07
如果x < 100
,我如何添加一个包含x
的新列y
,否则从 x < 100 的子集中添加具有下一个较小日期的行的 x 值。
我目前拥有的是这段代码。 它有效,但看起来效率不高:
df['y'] = df.x
df_ref = df.loc[df.x < 100].sort_values('date').copy()
df_ref.set_index('x', inplace=True)
for ix, row in df.iterrows():
if row.x >= 100:
delta = row.date - df_ref.date
delta_gt = delta.loc[delta > pd.Timedelta(0)]
if delta_gt.size > 0:
df.loc[ix, 'y'] = delta_gt.idxmin()
x date y
0 1 2022-02-01 1
1 5 2022-02-03 5
2 8 2022-02-06 8
3 103 2022-02-04 5
4 105 2022-02-05 5
5 112 2022-02-07 8
按日期排序,屏蔽大于 100 和ffill
的值,再次按索引排序:
(df.sort_values(by='date')
.assign(y=df['x'].mask(df['x'].gt(100)))
.assign(y=lambda d: d['y'].ffill())
.sort_index()
)
Output:
x date y
0 1 2022-02-01 1
1 5 2022-02-03 5
2 8 2022-02-06 8
3 103 2022-02-05 5
4 105 2022-02-05 5
5 112 2022-02-07 8
我们可以检查merge_asof
#df.date = pd.to_datetime(df.date)
df = df.sort_values('date')
out = pd.merge_asof(df,
df[df['x']<100].rename(columns={'x':'y'}),
on = 'date',
direction = 'backward').sort_values('x')
out
Out[160]:
x date y
0 1 2022-02-01 1
1 5 2022-02-03 5
4 8 2022-02-06 8
2 103 2022-02-05 5
3 105 2022-02-05 5
5 112 2022-02-07 8
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.