根据其他列的值有条件地更改系列的值

时间:2019-09-25 13:48:59

标签: python pandas dataframe

我正在使用具有以下结构的DataFrame体验/学习Python:

df = pd.DataFrame({"left_color"  : ["red", "green", "blue", "black", "white", ""],
                   "right_color" : ["red", "gray", "", "black", "red", ""],
                    "flag"       : [1, 2, 3, 1, 2, 3]})
print(df)

  left_color right_color  flag
0        red         red     1
1      green        gray     2
2       blue                 3
3      black       black     1
4      white         red     2
5                            3

我的目标是根据flagleft_color列的值有条件地更改right_color系列的值。具体来说:

  • 如果缺少left_color right_color,请将flag的值更改为numpy NaN;
  • 如果left_colorright_color不同,请将flag的值更改为0

这是我的尝试:

def myfunc(left_side, right_side, value):
    if (left_side == "") | (right_side == ""):
        value = np.nan
    if left_side != right_side:
        value = 0
df["flag"] = df.apply(lambda x: myfunc(x["left_color"], x["right_color"], x["flag"]), axis = 1)
print(df)

  left_color right_color  flag
0        red         red  None
1      green        gray  None
2       blue              None
3      black       black  None
4      white         red  None
5                         None

如您所见,我得到的结果不是我最初描述的结果。相反,我到处都有None值。这是我想要的结果:

  left_color right_color  flag
0        red         red     1
1      green        gray     0
2       blue               NaN
3      black       black     1
4      white         red     0
5                          NaN

我想了解我的错误以及解决方法。另外,我想看看是否有更多的 Pythonic 方法可以解决此问题,并且在计算上更有效。

3 个答案:

答案 0 :(得分:1)

您忘了在函数中返回值。

def myfunc(left_side, right_side, value):
    if (left_side == "") | (right_side == ""):
        return np.nan
    elif left_side != right_side:
        return 0
    else:
        return value

答案 1 :(得分:1)

您可以如下使用np.select。我很瘦,这很可能比自定义函数要快。

df.flag=np.select([df.left_color=='',df.right_color=='', df.right_color!=df.left_color,df.right_color==df.left_color],[np.nan,np.nan,0,1] )

输出

   left_color   right_color flag
0   red              red    1.0
1   green            gray   0.0
2   blue                    NaN
3   black            black  1.0
4   white             red   0.0
5                           NaN

答案 2 :(得分:1)

您要np.select

df['flag'] = np.select((df.left_color.eq("")|df.right_color.eq(""),
                        df.left_color.ne(df.right_color)),
                       (np.nan, 0), 
                       default=df.flag)

输出:

  left_color right_color  flag
0        red         red   1.0
1      green        gray   0.0
2       blue               NaN
3      black       black   1.0
4      white         red   0.0
5                          NaN