#python #pandas #dataframe
Вопрос:
У меня проблема. У меня есть фрейм данных . df_path
Это дает все значения, которые a host_id
может иметь в данном id
. Я хотел бы сделать из этого Одну Горячую Кодирующую матрицу. Т. е. я хотел бы, Hot Water
чтобы был сгенерирован новый столбец. Если определенный объект имеет значение Hot Water
, то вводится 1, если нет, то следует ввести 0.
Проблема в том , что host_id
с id
тем, что указано слишком часто df_one
, это должно произойти только один раз. Как мне это сделать правильно?
.melt
Функция и так далее должны остаться, и было бы неплохо, если бы она могла сочетаться с пандами.
d = {'host_id': [1, 1, 2], 'id': [10, 11, 20], 'value': ["Hot Water,Cold Water,Kitchen,Coffee", "Hot Water,Coffee,Something", "Hot Water,Coffee"]} df = pd.DataFrame(data=d) print(df) print(df.shape) print() df_path = df.copy() df_path.index = pd.MultiIndex.from_arrays(df_path[['host_id', 'id']].values.T, names=['host_id', 'id']) df_path = df_path['value'].str.split(',', expand=True) df_path = df_path.melt(ignore_index=False).dropna() df_path.reset_index(inplace=True) print(df_path) one_hot = pd.get_dummies(df_path['value']) df_one = df_path.drop('value',axis = 1) df_one = df_path.join(one_hot) print() print(df_one)
[OUT] # df host_id id value 0 1 10 Hot Water,Cold Water,Kitchen,Coffee 1 1 11 Hot Water,Coffee,Something 2 2 20 Hot Water,Coffee (3, 3) # df.shape # df_path host_id id variable value 0 1 10 0 Hot Water 1 1 11 0 Hot Water 2 2 20 0 Hot Water 3 1 10 1 Cold Water 4 1 11 1 Coffee 5 2 20 1 Coffee 6 1 10 2 Kitchen 7 1 11 2 Something 8 1 10 3 Coffee
Что у меня есть
# df_one host_id id variable value Coffee Cold Water Hot Water Kitchen 0 1 10 0 Hot Water 0 0 1 0 1 1 11 0 Hot Water 0 0 1 0 2 2 20 0 Hot Water 0 0 1 0 3 1 10 1 Cold Water 0 1 0 0 4 1 11 1 Coffee 1 0 0 0 5 2 20 1 Coffee 1 0 0 0 6 1 10 2 Kitchen 0 0 0 1 7 1 11 2 Something 0 0 0 0 8 1 10 3 Coffee 1 0 0 0 Something 0 0 1 0 2 0 3 0 4 0 5 0 6 0 7 1 8 0
Чего я хочу
host_id id value Coffee Cold Water Hot Water Kitchen Som. 0 1 10 Hot Water,Cold Water,Kitchen,Coffee 1 1 1 1 0 1 1 11 Hot Water,Coffee,Something 1 0 1 0 1 2 2 20 Hot Water,Coffee 1 0 1 0 0 (3, 8) # df_one.shape
Ответ №1:
Вы могли бы попробовать что-то вроде:
grouped_df_one = df_one.groupby(['id']).max()
И объедините его с вашим оригинальным df
df.merge(grouped_df_one, on='id')
Затем выберите нужные вам столбцы. Или вы уже можете выбрать нужные вам столбцы в grouped_df_one, например. grouped_df_one .iloc[:,3:]
В одной строке: df.merge(df_one.groupby(['id']).max().iloc[:,3:], on='id')
:
host_id id value Coffee Cold Water 0 1 10 Hot Water,Cold Water,Kitchen,Coffee 1 1 1 1 11 Hot Water,Coffee,Something 1 0 2 2 20 Hot Water,Coffee 1 0 Hot Water Kitchen Something 0 1 1 0 1 1 0 1 2 1 0 0
Ответ №2:
преобразуйте значение в список, разнесите, получите манекены и объедините.
#Создайте новый фрейм данных с отдельными элементами в df
df1=df.assign(value=df['value'].str.split(',')).explode('value', ignore_index=True)
#Сведите в таблицу частоту появления каждого элемента и объедините в df
df.merge(pd.crosstab([df1['id'],df1['host_id']], df1['value']).reset_index(), how='left', on=['id','host_id']) host_id id value Coffee Cold Water 0 1 10 Hot Water,Cold Water,Kitchen,Coffee 1 1 1 1 11 Hot Water,Coffee,Something 1 0 2 2 20 Hot Water,Coffee 1 0 Hot Water Kitchen Something 0 1 1 0 1 1 0 1 2 1 0 0
Комментарии:
1. Большое спасибо. Я попробовал ваш код, но результат не похож на то, что я хочу. Ценности повторяются сами собой. Форма такая
(9, 8)
2. Дубликатов нет, потому что, например, в первой строке
Hot Water
записано 1, а во второй строкеCold Water
записано 1, поэтому строки разные.3. Смотрите мои правки в соответствии с вашим запросом
4. Спасибо, но результат не похож на мой желаемый. Например, в разделе «Значение» указаны отдельные значения и «как
df
есть». Форма должна быть(3, 8)
5. Хорошо, какие критерии вы используете для сокращения строк?