我有一个如下数据框:
A
1 1000
2 1000
3 1001
4 1001
5 10
6 1000
7 1010
8 9
9 10
10 6
11 999
12 10110
13 10111
14 1000
我正尝试通过以下方式清理数据框: 对于每行的值大于前一行值的1.5倍或小于前一行值的0.5倍的行,请将其删除。 但是,如果前一行是拖放行,则必须与紧邻的前一个非拖放行进行比较。 (例如,我的数据框中的索引9、10或13) 所以最终的数据帧应该像这样:
A
1 1000
2 1000
3 1001
4 1001
6 1000
7 1010
11 999
14 1000
我的数据帧非常大,因此性能受到赞赏。
答案 0 :(得分:6)
我将一个系列传递给一个函数,并产生满足条件的行的索引值。
def f(s):
it = s.iteritems()
i, v = next(it)
yield i # Yield the first one
for j, x in it:
if .5 * v <= x <= 1.5 * v:
yield j # Yield the ones that satisfy
v = x # Update the comparative value
df.loc[list(f(df.A))] # Use `loc` with index values
# yielded by my generator
A
1 1000
2 1000
3 1001
4 1001
6 1000
7 1010
11 999
14 1000
答案 1 :(得分:1)
一种替代方法是使用itertools.accumulate来向前推最后一个有效值,然后过滤掉与原始值不同的值,例如:
from itertools import accumulate
def change(x, y, pct=0.5):
if pct * x <= y <= (1 + pct) * x:
return y
return x
# create a mask filtering out the values that are different from the original A
mask = (df.A == list(accumulate(df.A, change)))
print(df[mask])
输出
A
1 1000
2 1000
3 1001
4 1001
6 1000
7 1010
11 999
14 1000
只是个想法,请查看累计列(更改)与原始内容的比较:
A change
1 1000 1000
2 1000 1000
3 1001 1001
4 1001 1001
5 10 1001
6 1000 1000
7 1010 1010
8 9 1010
9 10 1010
10 6 1010
11 999 999
12 10110 999
13 10111 999
14 1000 1000
更新
要使其在函数调用中执行:
mask = (df.A == list(accumulate(df.A, lambda x, y : change(x, y, pct=0.5))))