在熊猫.loc []分配中访问下一行,上一行或当前行

时间:2018-12-09 16:18:59

标签: python pandas

在pandas文档cookbook的if-then部分下,我们可以根据使用if(getIntent().getExtras()!=null) String json=getIntent().getExtras().getString("json"); 在另一列中满足的条件,在一个列中分配值。

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.BBB=5之差大于或等于50的任何地方分配df.CCC。创建一个为我提供以下数据框的条件:

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

因为我对如何访问数据帧中当前行之上或之下的值这一普遍问题感兴趣(不一定解决这个玩具示例。)

mask = df['CCC'].current - df['CCC'].next >= 50 df.loc[mask, '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 对大熊猫进行此操作?

2 个答案:

答案 0 :(得分:1)

给予

>>> df
   AAA  BBB  CCC
0    4   10  100
1    5   20   50
2    6   30  -30
3    7   40  -50

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

>>> 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方法也足够。

答案 1 :(得分:0)

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

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