在 pandas .loc[] 赋值中访问下一行、上一行或当前行

Dav*_*vid 5 python pandas

在 pandas 文档说明书的 if-then 部分,我们可以根据使用loc[].

 df = pd.DataFrame({'AAA' : [4,5,6,7], 
'BBB' : [10,20,30,40],
'CCC' : [100,50,-30,-50]})
#    AAA  BBB  CCC
# 0    4   10  100
# 1    5   20   50
# 2    6   30  -30
# 3    7   40  -50

df.loc[df.AAA >= 5,'BBB'] = -1
#    AAA  BBB  CCC
# 0    4   10  100
# 1    5   -1   50
# 2    6   -1  -30
# 3    7   -1  -50
Run Code Online (Sandbox Code Playgroud)

但是,如果我想使用 编写涉及前一行或后一行的条件.loc[]怎么办?例如,假设我想分配当前行和下一行df.BBB=5之间的差值大于或等于 50 的任何位置。然后我想创建一个条件,该条件为我提供以下数据框:df.CCCdf.CCC

#    AAA  BBB  CCC
# 0    4    5  100 <-| 100 - 50 = 50, assign df.BBB = 5
# 1    5    5   50 <-| 50 -(-30)= 80, assign df.BBB = 5 
# 2    6   -1  -30 <-| 30 -(-50)= 20, don't assign df.BBB = 5
# 3    7   -1  -50 <-| (-50) -0 =-50, don't assign df.BBB = 5
Run Code Online (Sandbox Code Playgroud)

我怎样才能得到这个结果?

编辑 我希望找到的答案是这样的

mask = df['CCC'].current - df['CCC'].next >= 50
df.loc[mask, 'BBB'] = 5
Run Code Online (Sandbox Code Playgroud)

因为我对如何访问数据帧中正在考虑的当前行上方或下方的值的一般问题感兴趣。(不一定要解决这个玩具示例。)

diff() 将适用于我首先描述的示例,但是其他情况呢,例如,我们想要比较两个元素而不是减去它们?

如果我采用前一个数据框并且我想找到当前列条目与下一个条目不匹配的所有行,df.BBB然后df.CCC根据这些比较进行分配,该怎么办?

if df.BBB.current == df.CCC.next:
    df.CCC = 1

#    AAA  BBB  CCC     
# 0    4    5    1 <-|  5 ==  5, assign df.CCC = 1
# 1    5    5   50 <-|  5 != -1, do nothing
# 2    6   -1    1 <-| -1 == -1, assign df.CCC = 1
# 3    7   -1  -50 <-| -1 !=  0, do nothing
Run Code Online (Sandbox Code Playgroud)

有没有办法用熊猫来做到这一点.loc[]

tim*_*geb 2

给定

>>> df
   AAA  BBB  CCC
0    4   10  100
1    5   20   50
2    6   30  -30
3    7   40  -50
Run Code Online (Sandbox Code Playgroud)

您可以首先通过以下方式计算布尔掩码

>>> mask = df['CCC'].diff(-1) >= 50
>>> mask
0     True
1     True
2    False
3    False
Name: CCC, dtype: bool
Run Code Online (Sandbox Code Playgroud)

然后发出

>>> df.loc[mask, 'BBB'] = 5
>>> 
>>> df
   AAA  BBB  CCC
0    4    5  100
1    5    5   50
2    6   30  -30
3    7   40  -50
Run Code Online (Sandbox Code Playgroud)

更一般地,您可以计算偏移

>>> df['CCC_next'] = df['CCC'].shift(-1) # or df['CCC'].shift(-1).fillna(0)
>>> df
   AAA  BBB  CCC  CCC_next
0    4    5  100      50.0
1    5    5   50     -30.0
2    6   30  -30     -50.0
3    7   40  -50       NaN
Run Code Online (Sandbox Code Playgroud)

...然后做任何你想做的事,例如:

>>> df['CCC'].sub(df['CCC_next'], fill_value=0)
0    50.0
1    80.0
2    20.0
3   -50.0
dtype: float64
>>> mask = df['CCC'].sub(df['CCC_next'], fill_value=0) >= 50
>>> mask
0     True
1     True
2    False
3    False
dtype: bool
Run Code Online (Sandbox Code Playgroud)

尽管对于您问题中的具体问题,该diff方法已经足够了。