Python 在遍历dataframe时引用上一行

Python 在遍历dataframe时引用上一行,python,pandas,Python,Pandas,在遍历数据帧时,有没有一种简单的方法来引用前一行? 在下面的数据框中,我希望B列在A>1时变为1,并在A=1,1,df['B']) df[“B”]=np.其中(df['A']1的话),在这种情况下,我认为nan是可以的,因为它没有被OPS定义,这是完美的,而且比循环快得多!请更新此答案,以包括您的其他帖子的实际答案(实际上似乎很好)。谢谢您,Joseph。我现在也在这里重复了我的答案。如果这个答案有帮助,请投票并更正。

在遍历数据帧时,有没有一种简单的方法来引用前一行? 在下面的数据框中,我希望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] 
对于idx,df.iterrows()中的行:
如果df[“A”][idx]1:
df[“B”][idx]=1
其他:
df[“B”][idx]=df[“B”][idx-1]

我也尝试过使用
get_loc
,但完全迷路了,我肯定我错过了一个非常简单的解决方案

这就是你想要做的

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
[38]中的
:df=DataFrame(randn(10,2),columns=list('AB'))
In[39]:df['B']=np.nan
在[40]中:df.loc[df.A1,'B']=1
在[42]:df.ffill()中
出[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
这里有类似的问题:。
我的印象是熊猫应该处理迭代,我们不应该自己做。。。因此,我选择使用DataFrame“apply”方法

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

您可以使用dataframe“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:我相当确定这将减慢应用操作,但我没有进行任何测试以确定其速度。

尝试这样做:如果第一个值既不是
=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)
df[“B”]=无
df[“B”]=np.其中(df['A']>=1,1,df['B'])
df[“B”]=np.其中(df['A']<-1,-1,df['B'])
df=df.ffill().fillna(0)

这解决了前面提到的问题,但引用前一行的真正解决方案是使用
.shift()
.index()-1

您可以使用一个变量,在每个循环结束时将其设置为当前行,并将下一行与循环开始时的行进行比较。谢谢,我知道我遗漏了一个非常简单的解决方案。可能是+1的重复,但如果第一个元素是NaN,那么它将失败,不是吗?(也就是说,你不需要一个额外的
.fillna(0)
什么的吗?)它可以在B中生成一个
nan
(对于前n个元素,如果不是abs>1的话),在这种情况下,我认为
nan
是可以的,因为它没有被OPS定义,这是完美的,而且比循环快得多!请更新此答案,以包括您的其他帖子的实际答案(实际上似乎很好)。谢谢您,Joseph。我现在也在这里重复了我的答案。如果这个答案有帮助,请投票并更正。