基于条件更改行值的 Python for 循环可以正常工作,但不会更改 pandas 数据帧上的值?

Posted

技术标签:

【中文标题】基于条件更改行值的 Python for 循环可以正常工作,但不会更改 pandas 数据帧上的值?【英文标题】:Python for-loop to change row value based on a condition works correctly but does not change the values on pandas dataframe? 【发布时间】:2021-12-20 16:04:29 【问题描述】:

我刚刚进入 Python,我正在尝试制作一个 for-loop,它在每一行上循环,并根据给定条件在每次迭代中随机选择两列并更改它们的值。 for-loop 工作没有任何问题;但是,dataframe 上的结果不会改变。

一个可重现的例子:

df= pd.DataFrame('A': [10,40,10,20,10],
                  'B': [10,10,50,40,50],
                  'C': [10,20,10,10,10],
                  'D': [10,30,10,10,50],
                  'E': [10,10,40,10,10],
                  'F': [2,3,2,2,3])

df:


    A   B   C   D   E   F
0   10  10  10  10  10  2
1   40  10  20  30  10  3
2   10  50  10  10  40  2
3   20  40  10  10  10  2
4   10  50  10  50  10  3

这是我的for-loop; for 循环遍历所有行并检查列 F 上的值是否 = 2;它随机选择值为 10 的两列并将它们更改为 100。

for index, i in df.iterrows():
  if i['F'] == 2:
    i[i==10].sample(2, axis=0)+100
    print(i[i==10].sample(2, axis=0)+100)

这是循环的输出:

E    110
C    110
Name: 0, dtype: int64
C    110
D    110
Name: 2, dtype: int64
C    110
D    110
Name: 3, dtype: int64

这是dataframe 的预期外观:

df:


    A   B   C   D   E   F
0   10  10  110 10  110 2
1   40  10  20  30  10  3
2   10  50  110 110 40  2
3   20  40  110 110 10  2
4   10  50  10  50  10  3

但是,dataframe 上的列并没有改变。知道出了什么问题吗?

【问题讨论】:

【参考方案1】:

这一行:

i[i==10].sample(2, axis=0)+100

.sample 返回一个新数据帧,因此原始数据帧 (df) 根本没有更新。

试试这个:

for index, i in df.iterrows():
    if i['F'] == 2:
        cond = (i == 10)

        # You can only sample 2 rows if there are at
        # least 2 rows meeting the condition
        if cond.sum() >= 2:
            idx = i[cond].sample(2).index
            i[idx] += 100
            print(i[idx])

【讨论】:

按预期工作,非常感谢。只是一个问题,如果我们想从样本中排除一列,例如列 E 或 D 和 E,该怎么办? 你改变条件:cond = (i == 10) & not i.index.isin(['E', 'D', 'F']) 它没有工作SyntaxError: invalid syntax 错误来自不是。我尝试将& 更改为and 显示错误ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all(). 我也尝试使用not in 并添加( ),但它们都不起作用。 我的意思是在我的第一条评论中。如果我希望循环跳过特定列以使其值不会改变怎么办?例如,列 E 有 10,但循环应该从循环中跳过它(排除它),并且它的值不应该改变。非常感谢。【参考方案2】:

你should not modify the original df in place。复制并迭代:

df2 = df.copy()
for index, i in df.iterrows():
    if i['F'] == 2:
        s = i[i==10].sample(2, axis=0)+100
        df2.loc[index,i.index.isin(s.index)] = s

【讨论】:

以上是关于基于条件更改行值的 Python for 循环可以正常工作,但不会更改 pandas 数据帧上的值?的主要内容,如果未能解决你的问题,请参考以下文章

PySpark:如何根据其他行值的值更改行+列的值

while,do while,for循环语句

for循环

不同的 SELECTs 子句更改行数(具有相同的 WHERE 条件)

如何根据剑道网格中的特定列条件更改行的颜色以获取角度

提供非布尔值的循环条件