Python 访问pandas.loc[]分配中的下一行、上一行或当前行

Python 访问pandas.loc[]分配中的下一行、上一行或当前行,python,pandas,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.A

在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
但是,如果我想使用
.loc[]
编写一个涉及上一行或下一行的条件,该怎么办?例如,如果当前行的
df.CCC
与下一行的
df.CCC
之间的差值大于或等于50,则我想分配
df.BBB=5
。然后我想创建一个条件,为我提供以下数据帧:

#    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
因为我对如何访问数据帧中当前行上方或下方的值的一般问题感兴趣(不一定解决这个示例)

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
如果df.BBB.current==df.CCC.next:
df.CCC=1
#AAA BBB CCC
#0451

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

>>> mask = df['CCC'].diff(-1) >= 50
>>> mask
0     True
1     True
2    False
3    False
Name: CCC, dtype: bool
然后发布

>>> 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

更一般地说,您可以计算移位

>>> 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
。。。然后做任何你想做的事,比如:

>>> 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

尽管对于您问题中的特定问题,
diff
方法已足够。

您可以使用枚举函数同时访问行及其索引。因此,您可以根据当前行的索引获取上一行和下一行。我在下面提供了一个示例脚本供您参考:

import pandas as pd

df = pd.DataFrame({'AAA' : [4,5,6,7],
                   'BBB' : [10,20,30,40],
                   'CCC' : [100,50,-30,-50]}, index=['a','b','c','d'])

print('row_pre','row_pre_AAA','row','row_AA','row_next','row_next_AA')
for irow, row in enumerate(df.index):
    if irow==0:
        row_next = df.index[irow+1]
        print('row_pre', "df.loc[row_pre,'AAA']", row, df.loc[row,'AAA'], row_next, df.loc[row_next,'AAA'])
    elif irow>0 and irow<df.index.size-1:
        row_pre = df.index[irow-1]
        row_next = df.index[irow+1]
        print(row_pre, df.loc[row_pre,'AAA'], row, df.loc[row,'AAA'], row_next, df.loc[row_next,'AAA'])
    else:
        row_pre = df.index[irow-1]
        print(row_pre, df.loc[row_pre,'AAA'], row, df.loc[row,'AAA'], 'row_next', "df.loc[row_next,'AAA']")


通过
df['CCC'].diff(-1)>=50创建的布尔序列在本例中有效。尽管如此,我还是希望访问以前和以后的元素
diff()
为我们获取当前元素和后续元素之间的差异;我也想这么做,但是直接。我将编辑我的问题,使之更加具体。
>>> 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
import pandas as pd

df = pd.DataFrame({'AAA' : [4,5,6,7],
                   'BBB' : [10,20,30,40],
                   'CCC' : [100,50,-30,-50]}, index=['a','b','c','d'])

print('row_pre','row_pre_AAA','row','row_AA','row_next','row_next_AA')
for irow, row in enumerate(df.index):
    if irow==0:
        row_next = df.index[irow+1]
        print('row_pre', "df.loc[row_pre,'AAA']", row, df.loc[row,'AAA'], row_next, df.loc[row_next,'AAA'])
    elif irow>0 and irow<df.index.size-1:
        row_pre = df.index[irow-1]
        row_next = df.index[irow+1]
        print(row_pre, df.loc[row_pre,'AAA'], row, df.loc[row,'AAA'], row_next, df.loc[row_next,'AAA'])
    else:
        row_pre = df.index[irow-1]
        print(row_pre, df.loc[row_pre,'AAA'], row, df.loc[row,'AAA'], 'row_next', "df.loc[row_next,'AAA']")

row_pre row_pre_AAA row row_AA row_next row_next_AA
row_pre df.loc[row_pre,'AAA'] a 4 b 5
a 4 b 5 c 6
b 5 c 6 d 7
c 6 d 7 row_next df.loc[row_next,'AAA']