Pandas 根据另一列条件更改列的值

数据挖掘 数据挖掘 熊猫
2021-10-04 03:46:11

我在 column1 中有值,在 column2 中有列。我想要实现的目标: 条件:如果 column1 < 30,则 column2 == 2 保留为 2,如果 column1 > 90,则 elsif 更改为 3。

这是我到目前为止所做的,问题是 2 不会更改为 3,其中 column1 > 90。

filter1 = data['column1']
for x in filter1:
    if x < 30:
        data['column2'] = data['column2'].replace([2], [2])
    else:
        data['column2'] = data['Output'].replace([2], [3])
3个回答

我想要达到的目标: 条件: where column2 == 2 leave to be 2 if column1 < 30 elsif change to 3 if column1 > 90

这可以简化为where (column2 == 2 and column1 > 90) set column2 to 3. column1 < 30部分是多余的,因为如果 的值column2只会从 2 变为 3 column1 > 90

在您提供的代码中,您使用的是 pandas 函数replace,它在整个系列上运行,如参考中所述:

系列的值被动态替换为其他值。这与使用 .loc 或 .iloc 进行更新不同,后者要求您指定要使用某个值更新的位置。

这意味着对于for x in filter1您的代码的每次迭代都会执行全局替换,这不是您想要做的 - 您想要更新column2对应于xfrom column1(您正在迭代)的特定行。

问题是 2 不会更改为 3 其中 column1 > 90

这真的很奇怪。我希望您提供的代码在column2遇到 2 时立即将每个实例更改为 3 x >= 30,如您的代码条件语句(else分支的执行)所指示的那样。这种差异可能源于您正在分配对column2列执行的全局替换的结果Output(其内容未知)。无论如何,如果你想让你的程序在特定条件下做某事,比如x > 90,应该在代码中明确说明。您还应该注意,该语句data['column2'] = data['column2'].replace([2], [2])没有取得任何成果,因为 2 被替换为 2 并且同一列既是源又是目标。

您可以用来解决此特定任务的是布尔掩码(或查询方法)。在这个问题中,两者都得到了很好的解释

在您的情况下,使用布尔掩码将是最简单的方法:

mask = (data['column2'] == 2) & (data['column1'] > 90)
data['column2'][mask] = 3

第一行构建一系列布尔值(真/假),指示是否满足所提供的条件。第二行将值 3 分配给column2掩码为 True 的那些行。

我以稍微不同的方式成功地解决了这个问题。

import numpy as np

data['column2'] = np.where((data['column1'] < 30)
                           & (data['column2'] ==2), #Identifies the case to apply to
                           data['column2'],      #This is the value that is inserted
                           data['column2'])      #This is the column that is affected
data['column2'] = np.where((data['column1'] > 90)
                           & (data['column2'] ==2), #For rows with column1 > 90
                           data['column3'],      #We place column3 values
                           data['column2'])      #In column two

这比循环有点冗长,但我发现它是使用 pandas 进行此类数据操作的最直观的方式。

当我在等待答案时,我也得到了一些工作

def myfunc(x,y):
    if x <= 30 and y == 2:
        return y
    elif x > 90 and y == 2:
        return y + 1
    else:
        return y

data['column2'] = data.apply(lambda x: myfunc(x.column1, x.column2), axis=1)