根据最后一个未过滤的值过滤百分比范围内的值

问题描述 投票:0回答:1

我有一个数据框,其中“贸易”列填充了一些正值;其余的都是 NaN 值。

Trade
 100
 Nan
 Nan
 101
 Nan
 102
 Nan
 98
 107
 Nan
 101
 Nan
 98
 Nan
 Nan
 94

在非 Nan 值中,我需要一个矢量化解决方案来删除落在最后一个未删除值的 95%-105% 值范围内的值。最终结果应该是这样的:

Trade
 100
 Nan
 Nan
 Nan
 Nan
 Nan
 Nan
 Nan
 107
 Nan
 101
 Nan
 Nan
 Nan
 Nan
 94
python pandas numpy vectorization algebra
1个回答
0
投票

正如其他人指出的那样,由于算法和结果行之间存在依赖性,因此不会有纯粹的“单通道”矢量化解决方案。然而,您仍然可以采取“缩小”窗口的方法来解决这个问题,同时尝试最小化所需的迭代步骤数。

import pandas as pd
from pandas import NA

df = pd.DataFrame(
    {'trade': [100, NA, NA, 101, NA, 102, NA, 98, 107, NA, 101, NA, 98, NA, NA, 94]}
).astype({'trade': 'Int32'})

tmp = df.dropna()
valid = [0]
while valid[-1] < tmp.index[-1]:
    chunk = tmp.loc[valid[-1]:, 'trade'] # get window of all unprocessed data
    target = chunk.iat[0]
    valid.append(                        # find the first boundary
        chunk.between(target * .95, target * 1.05).idxmin() 
    )

print(
    f'{valid = }',  # [0, 8, 10, 15] (while loop took len(valid) iterations)
    df.assign(      # mask over values not in `valid`
        cleaned=lambda d: d['trade'].where(d.index.isin(valid)),
    ),
    sep='\n\n',
)
# valid = [0, 8, 10, 15]
#
#     trade  cleaned
# 0     100      100
# 1    <NA>     <NA>
# 2    <NA>     <NA>
# 3     101     <NA>
# 4    <NA>     <NA>
# 5     102     <NA>
# 6    <NA>     <NA>
# 7      98     <NA>
# 8     107      107
# 9    <NA>     <NA>
# 10    101      101
# 11   <NA>     <NA>
# 12     98     <NA>
# 13   <NA>     <NA>
# 14   <NA>     <NA>
# 15     94       94

我将其称为“缩小”窗口方法的原因是因为 while 循环的每个周期都将在 DataFrame 的较小块上工作,直到我们消耗掉所有数据帧。这使我们能够利用尽可能多的 DataFrame/Series 方法,因此我们不会在 Python 级别进行任何数据处理。

© www.soinside.com 2019 - 2024. All rights reserved.