列操作以前一行为条件

时间:2018-05-22 15:36:51

标签: python pandas

我认为存在类似的问题,但找不到它们。我安装了Pandas 0.19.2。我有一个大的数据帧,对于每个行值,我想根据某些逻辑条件为同一列继承前一行的值。

下面是一个蛮力双循环解决方案的小例子。实现这一目标的最有效方法是什么?是否有可能以矢量化的方式解决这个问题?

import pandas as pd
import numpy as np

np.random.seed(10)
df = pd.DataFrame(np.random.uniform(low=-0.2, high=0.2, size=(10,2) ))
print(df)

for col in df.columns:
    prev = None
    for i,r in df.iterrows():
        if prev is not None:
            if (df[col].loc[i]<= prev*1.5) and (df[col].loc[i]>= prev*0.5):
                df[col].loc[i] = prev

        prev = df[col].loc[i]
print(df)

输出:

          0         1
0  0.108528 -0.191699
1  0.053459  0.099522
2 -0.000597 -0.110081
3 -0.120775  0.104212
4 -0.132356 -0.164664
5  0.074144  0.181357
6 -0.198421  0.004877
7  0.125048  0.045010
8  0.125048 -0.083250
9  0.125048  0.085830

编辑:请注意,只要满足逻辑条件,就可以多次携带一个值。

2 个答案:

答案 0 :(得分:1)

prev = df.shift()
replace_mask = (0.5 * prev <= df) & (df <= 1.5 * prev)
df = df.where(~replace_mask, prev)

答案 1 :(得分:0)

我想出了这个:

keep_going = True
while keep_going:
    df = df.mask((df.diff(1) / df.shift(1)<0.5) & (df.diff(1) / df.shift(1)> -0.5) & (df.diff(1) / df.shift(1)!= 0)).ffill()
    trimming_to_do = ((df.diff(1) / df.shift(1)<0.5) & (df.diff(1) / df.shift(1)> -0.5) & (df.diff(1) / df.shift(1)!= 0)).values.any()
    if not trimming_to_do:
        keep_going= False

给出了期望的结果(至少在这种情况下):

print(df)
          0         1
0  0.108528 -0.191699
1  0.053459  0.099522
2 -0.000597 -0.110081
3 -0.120775  0.104212
4 -0.120775 -0.164664
5  0.074144  0.181357
6 -0.198421  0.004877
7  0.125048  0.045010
8  0.125048 -0.083250
9  0.125048  0.085830