Условно изменить значения Серии на основе значений других столбцов - PullRequest
1 голос
/ 25 сентября 2019

Я испытываю / изучаю Python с DataFrame, имеющим следующую структуру:

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

Моя цель состоит в том, чтобы условно изменить значения серии flag на основе значений left_colorи right_color столбцы.В частности:

  • Если left_color отсутствует или right_color отсутствует, измените значение flag на numpy NaN;
  • Если left_color отличается от right_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 способ решения этой проблемы, который в вычислительном отношении более эффективен.

Ответы [ 4 ]

1 голос
/ 25 сентября 2019

Вы можете использовать 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
1 голос
/ 25 сентября 2019

Вы хотите 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
1 голос
/ 25 сентября 2019

Вы забыли вернуть значение в вашей функции.

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
0 голосов
/ 25 сентября 2019

Альтернативная форма с использованием логическая идентификация :

c1=df.eq('').any(axis=1)
df.loc[c1,'flag']=np.nan
df.loc[df['left_color'].ne(df['right_color'])&~c1,'flag']=0
print(df)
  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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...