迭代数据帧时引用上一行

时间:2013-05-22 17:46:56

标签: python pandas

在迭代数据帧时是否有一种简单的方法可以引用上一行? 在以下数据框架中,我希望B列在A > 1时更改为1,并且在A < -1更改为-1时保持为1。

In [11]: df
Out[11]:
                    A    B
2000-01-01  -0.182994    0
2000-01-02   1.290203    0
2000-01-03   0.245229    0
2000-01-08  -1.230742    0
2000-01-09   0.534939    0
2000-01-10   1.324027    0

这是我试过的,但显然你不能只从索引中减去1:

for idx,row in df.iterrows():
    if df["A"][idx]<-1:
        df["B"][idx] = -1
    elif df["A"][idx]>1:
        df["B"][idx] = 1
    else: 
        df["B"][idx] = df["B"][idx-1] 

我也试过使用get_loc但是完全迷失了,我确定我错过了一个非常简单的解决方案!

3 个答案:

答案 0 :(得分:1)

这是你想要做的事情?

In [38]: df = DataFrame(randn(10,2),columns=list('AB'))

In [39]: df['B'] = np.nan

In [40]: df.loc[df.A<-1,'B'] = -1

In [41]: df.loc[df.A>1,'B'] = 1

In [42]: df.ffill()
Out[42]: 
          A  B
0 -1.186808 -1
1 -0.095587 -1
2 -1.921372 -1
3 -0.772836 -1
4  0.016883 -1
5  0.350778 -1
6  0.165055 -1
7  1.101561  1
8 -0.346786  1
9 -0.186263  1

答案 1 :(得分:0)

这里有类似的问题:Reference values in the previous row with map or apply
我的印象是,大熊猫应该处理迭代,我们不应该自己做...因此,我选择使用DataFrame'apply'方法。

以上是我在上面链接的其他问题上发布的相同答案......

您可以使用数据框'apply'功能,并利用未使用的'kwargs'参数存储上一行。

import pandas as pd

df = pd.DataFrame({'a':[0,1,2], 'b':[0,10,20]})

new_col = 'c'

def apply_func_decorator(func):
    prev_row = {}
    def wrapper(curr_row, **kwargs):
        val = func(curr_row, prev_row)
        prev_row.update(curr_row)
        prev_row[new_col] = val
        return val
    return wrapper

@apply_func_decorator
def running_total(curr_row, prev_row):
    return curr_row['a'] + curr_row['b'] + prev_row.get('c', 0)

df[new_col] = df.apply(running_total, axis=1)

print(df)
# Output will be:
#    a   b   c
# 0  0   0   0
# 1  1  10  11
# 2  2  20  33

此示例使用装饰器将前一行存储在字典中,然后在Pandas在下一行调用它时将其传递给该函数。

免责声明1:'prev_row'变量在第一行开始为空,因此在apply函数中使用它时,我必须提供一个默认值以避免'KeyError'。

免责声明2:我相当肯定这会使申请操作变慢,但我没有做任何测试来计算出多少。

答案 2 :(得分:0)

试试这个:如果第一个值既不是.c,也不是>= 1设置为< -1或者您喜欢的任何内容。

0

这解决了所述问题,但引用前一行的真正解决方案是使用df["B"] = None df["B"] = np.where(df['A'] >= 1, 1,df['B']) df["B"] = np.where(df['A'] < -1, -1,df['B']) df = df.ffill().fillna(0) .shift()