繁体   English   中英

在 pandas DataFrame 的子集中查找具有最接近值的行

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM