我有一个数据框,其中“贸易”列填充了一些正值;其余的都是 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
正如其他人指出的那样,由于算法和结果行之间存在依赖性,因此不会有纯粹的“单通道”矢量化解决方案。然而,您仍然可以采取“缩小”窗口的方法来解决这个问题,同时尝试最小化所需的迭代步骤数。
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 级别进行任何数据处理。