Новый столбец с помощью lambda if-еще, но получение NaNs

#python #pandas

#python #панды

Вопрос:

У меня есть фрейм данных, который выглядит следующим образом:

      col1    label 
 0  value1  label1  
 1  value2  label2   
 2  value2  label1 label2  
  

Для каждой метки я хочу создать новый столбец, указывающий, встречается ли эта метка в этой строке:

      col1    label        label1  label2
 0  value1  label1          1       0
 1  value2  label2          0       1
 2  value2  label1 label2   1       1
  

Что я пробовал:

 #iterating through all occuring labels (strings)
for label in labels:
    grouped[label] = df.apply(lambda row: 1 if label in row['label'] else 0, axis=1))
  

Но это приводит к NaNs:

       col1    label        label1  label2
 0  value1  label1          NaN      NaN
 1  value2  label2          NaN      NaN
 2  value2  label1 label2   NaN      NaN
  

Где моя ошибка? И / или есть ли лучший способ решить эту проблему?

Редактировать: найдена моя ошибка, в цикле есть два разных фрейма данных, которые должны быть только одним:

 for label in labels:
    grouped[label] = df.apply(lambda row: 1 if label in row['label'] else 0, axis=1))
  

Комментарии:

1. Здесь нам не хватает информации. Что такое «подкатегория» и «метки» здесь. Кроме того, в строке номер 2 эти строки разделены пробелом?

2. Использовать df = df.join(df['label'].str.get_dummies(' '))

3. @jezrael отлично, это должно быть ответом. Но все же, почему мое решение не работает точно?

4. может быть, изменить grouped[label] на df[label] in цикл

5. проверено, для меня работает хорошо, только удалить последний )

Ответ №1:

Где моя ошибка? И / или есть ли лучший способ решить эту проблему?

Возникает ошибка при неправильном DataFrame назначении grouped , как я упоминал в комментариях, также удаляется последнее ) :

 for label in labels:
    df[label] = df.apply(lambda row: 1 if label in row['label'] else 0, axis=1)
  

Решение, не являющееся циклом, должно быть проверено Series.str.contains и преобразовано True/False в 1/0 by Series.view :

 labels = ['label1','label2']
#iterating through all occuring labels (strings)
for label in labels:
    df[label] = df['label'].str.contains(label).view('i1')
print (df)
     col1          label  label1  label2
0  value1         label1       1       0
1  value2         label2       0       1
2  value2  label1 label2       1       1
  

Если значения разделены пробелами, возможно использование Series.str.get_dummies :

 df = df.join(df['label'].str.get_dummies(' '))