首页 > 解决方案 > Pandas - 循环控制 - 根据列值比较控制循环的行为

问题描述

假设我有一个 Pandas DataFrame,如下所示:

Row | Column1 | Column2 | Column3
0 | abc | 10 | NY
1 | abc | 20 | NY
2 | abc | 15 | CA
3 | xyz | 10 | RI
4 | xyz | 30 | NV
5 | lmn | 15 | MN

现在,我想对 column2 和 column3 的值进行多项操作,但前提是 column1 的值发生变化。也就是说,循环应该遍历前三行,并在值更改时激活不同的代码。在传统语言中是这样的:

prev = df[0:1]
    for row in df:
       if prev.column1 == row.column1:
          <some code>
          continue
       else:
          <some other code>
    
       prev = row

目前,我尝试过的上述代码的 python 等效项对我不起作用,因为它说该系列的真值是模棱两可的。如果我通过.any()在条件上使用来解决这个问题,那么对于 column1 值的第一次更改它可以正常工作,但随后会抛出;bool 没有属性“任何”。

提前感谢您的帮助。

标签: pythonpandasloopscomparisonrow

解决方案


  1. 您可以使用.shift()逐行比较列中的值。
  2. 您可以np.where()根据条件和操作更改数据。

首先,让我们创建条件:

condition = (df.shift()['Column1'] != df['Column1']) & df.index > 0

  1. 此条件将行标记为TrueFalse中的值Column1是否与前一行的Column1值不同(df.shift()['Column1'] != df['Column1'])
  2. 但是,这也会标记第一行,因此您可以添加df.index > 0另一个条件来忽略第一行。

接下来,我们根据条件对dataframe进行一些操作:

df['Column2'] = np.where(condition, df['Column2'] + 100, df['Column2'])

df['Column3'] = np.where(condition, df['Column3'] + ' (adjusted)', df['Column3'])

  1. 使用np.where(),您传递的第一个参数condition是您刚刚创建的自定义变量。

  2. 如果第一个参数 ( ) 是,您将传递的第二个参数是您想要进行的任何操作。例如,或conditionTruedf['Column2'] + 100df['Column3'] + ' (adjusted)'

  3. 您将传递的第三个参数condition是如果is应该返回什么False。在这种情况下,只需返回列值的原始值,方法是在列中放入df['Column2']ordf['Column3']


import pandas as pd, numpy as np
condition = (df.shift()['Column1'] != df['Column1']) & df.index > 0
df['Column2'] = np.where(condition, df['Column2'] + 100, df['Column2'])
df['Column3'] = np.where(condition, df['Column3'] + ' (adjusted)', df['Column3'])
df
Out[22]: 
   Row Column1  Column2        Column3
0    0     abc       10             NY
1    1     abc       20             NY
2    2     abc       15             CA
3    3     xyz      110  RI (adjusted)
4    4     xyz       30             NV
5    5     lmn      115  MN (adjusted)

推荐阅读