Как заменить значения в колонках DataFrame в зависимости от значений в заданной колонке
Создал такой DataFrame. Здесь есть колонка Cuisine Style. Для использования в машинном алгоритме мне нужно создать категориальные признаки на основе элементов, которые есть в данной колонке. Сделал. Теперь, мне нужно для этих категориальных признаков проставить значение 1 для тех строк, где в поле Cuisine Style есть название колонки из категориальных признаков.
Я использовал код:
for l in list_of_cuisune:
df[l] = df.apply(lambda x: 1 if l in x['Cuisine Style'] else 0, axis = 1)
Ранее создал список list_of_cuisune и загнал туда все элементы из колонки Cuisine Style.
То есть логика такая у меня была: я создал список всех элементов из колонки Cuisine Style, на их основе создал новые колонки для новых признаков в датасете. Дальше, я как бы иду по строкам и смотрю - если в Cuisine Style есть слово из list_of_cuisune, то в соответствующую колонку признака ставлю 1, иначе - оставляю 0.
Код работает, но есть одна проблема - если элемент из списка list_of_cuisune (он же признак в датасете) состоит из более, чем одного слова, то оно не хочет корректно сравнивать l in x['Cuisine Style'] и проставлять 1.
Ответы (1 шт):
Воспользуйтесь sklearn.preprocessing.MultiLabelBinarizer:
from yaml import safe_load
from sklearn.preprocessing import MultiLabelBinarizer
mlb = MultiLabelBinarizer(sparse_output=True)
df = pd.read_csv(r"D:\download\main_task.csv")
tmp = df["Cuisine Style"].dropna().apply(safe_load).dropna()
X = pd.DataFrame.sparse.from_spmatrix(
mlb.fit_transform(tmp),
columns=mlb.classes_,
index=tmp.index)
результат:
In [39]: X
Out[39]:
Afghani African Albanian American Arabic ... Vietnamese Welsh Wine Bar Xinjiang Yunnan
0 0 0 0 0 0 ... 0 0 0 0 0
2 0 0 0 0 0 ... 0 0 0 0 0
4 0 0 0 0 0 ... 0 0 0 0 0
6 0 0 0 0 0 ... 0 0 0 0 0
7 0 0 0 0 0 ... 0 0 0 0 0
... ... ... ... ... ... ... ... ... ... ... ...
39995 0 0 0 0 0 ... 0 0 0 0 0
39996 0 0 0 1 0 ... 0 0 0 0 0
39997 0 0 0 0 0 ... 0 0 0 0 0
39998 0 0 0 0 0 ... 0 0 0 0 0
39999 0 0 0 0 0 ... 0 0 0 0 0
[30717 rows x 125 columns]
можно также объединить получившийся разреженный DataFrame с оригинальным, но при этом он превратиться в обычный (dense) DataFrame:
res = df.join(X, how="left")
результат:
In [41]: res
Out[41]:
Restaurant_id City Cuisine Style Ranking Rating ... Vietnamese Welsh \
0 id_5569 Paris ['European', 'French', 'International'] 5570.0 3.5 ... 0.0 0.0
1 id_1535 Stockholm NaN 1537.0 4.0 ... NaN NaN
2 id_352 London ['Japanese', 'Sushi', 'Asian', 'Gril... 353.0 4.5 ... 0.0 0.0
3 id_3456 Berlin NaN 3458.0 5.0 ... NaN NaN
4 id_615 Munich ['German', 'Central European', 'Vege... 621.0 4.0 ... 0.0 0.0
... ... ... ... ... ... ... ... ...
39995 id_499 Milan ['Italian', 'Vegetarian Friendly', '... 500.0 4.5 ... 0.0 0.0
39996 id_6340 Paris ['French', 'American', 'Bar', 'Europ... 6341.0 3.5 ... 0.0 0.0
39997 id_1649 Stockholm ['Japanese', 'Sushi'] 1652.0 4.5 ... 0.0 0.0
39998 id_640 Warsaw ['Polish', 'European', 'Eastern Euro... 641.0 4.0 ... 0.0 0.0
39999 id_4824 Milan ['Spanish'] 4827.0 3.0 ... 0.0 0.0
Wine Bar Xinjiang Yunnan
0 0.0 0.0 0.0
1 NaN NaN NaN
2 0.0 0.0 0.0
3 NaN NaN NaN
4 0.0 0.0 0.0
... ... ... ...
39995 0.0 0.0 0.0
39996 0.0 0.0 0.0
39997 0.0 0.0 0.0
39998 0.0 0.0 0.0
39999 0.0 0.0 0.0
[40000 rows x 136 columns]
