#python #python-3.x #pandas #dataframe #merge
Вопрос:
У меня есть два фрейма данных, которые выглядят так (реальные больше):
DF1:
Alliances_names | Значение 1 |
---|---|
cgc inc / nshow ltd / noracle inc | 500 |
steam / nsoap jv | NaN |
saints bd | 8 |
watrloo jv / ncgc inc / nflow inc | 19 |
DF2:
Компания | Number1 | Number2 |
---|---|---|
Steam | 15 | y |
soap jv | 2000 | n |
cgc inc | 4565 | n |
показать ооо | 1 | n |
flow inc | 1111 | y |
watrloo jv | 6756 | n |
Я должен объединить эти два фрейма данных со столбцами альянсов и компаний. Если это компания в альянсе, я должен добавить эту информацию в строку. (В DF1 есть разделитель / n между компаниями)
Результат должен быть таким:
Alliances_names | Значение 1 | Компания | Number1 | Number2 |
---|---|---|---|---|
cgc inc / nshowltd /noracle inc | 500 | cgc inc | 4565 | n |
cgc inc / nshowltd /noracle inc | 500 | показать ооо | 1 | n |
steam / nsoap jv | NaN | Steam | 15 | y |
steam / nsoap jv | NaN | soap jv | 2000 | n |
saints bd | 8 | NaN | NaN | NaN |
watrloo jv / ncgc inc / nflow inc | 19 | watrloo jv | 6756 | n |
watrloo jv / ncgc inc / nflow inc | 19 | cgc inc | 4565 | n |
watrloo jv / ncgc inc / nflow inc | 19 | flow inc | 1111 | y |
Мне нужно дублировать название альянсов для каждой компании в этом. Я попытался разделить компании в «название альянса» и создать еще один столбец со списками компаний в каждой ячейке, но «isin» не очень хорошо с этим справился, и я не смог создать фреймы данных с дубликатами.
Ответ №1:
- Создайте отдельный столбец (называемый «Company») с отдельными названиями компаний, используя
split
иexplode
. merge
два фрейма данных в столбце «Компания».
df1["Company"] = df1["Alliances_names"].str.split("/n")
df1 = df1.explode("Company")
output = df1.merge(df2, on="Company", how="left")
>>> output
Alliances_names Value1 Company Number1 Number2
0 cgc inc/nshow ltd/noracle inc 500.0 cgc inc 4565.0 n
1 cgc inc/nshow ltd/noracle inc 500.0 show ltd 1.0 n
2 cgc inc/nshow ltd/noracle inc 500.0 oracle inc NaN NaN
3 steam/nsoap jv NaN steam 15.0 y
4 steam/nsoap jv NaN soap jv 2000.0 n
5 saints bd 8.0 saints bd NaN NaN
6 watrloo jv/ncgc inc/nflow inc 19.0 watrloo jv 6756.0 n
7 watrloo jv/ncgc inc/nflow inc 19.0 cgc inc 4565.0 n
8 watrloo jv/ncgc inc/nflow inc 19.0 flow inc 1111.0 y
Редактировать:
Чтобы сохранить только строки, в которых находятся все Alliances_names df2
, вы можете сделать:
output = output[output["Alliances_names"].str.split("/n").map(set(df2["Company"]).issuperset)]
>>> output
Alliances_names Value1 Company Number1 Number2
3 steam/nsoap jv NaN steam 15.0 y
4 steam/nsoap jv NaN soap jv 2000.0 n
6 watrloo jv/ncgc inc/nflow inc 19.0 watrloo jv 6756.0 n
7 watrloo jv/ncgc inc/nflow inc 19.0 cgc inc 4565.0 n
8 watrloo jv/ncgc inc/nflow inc 19.0 flow inc 1111.0 y
Комментарии:
1. Еще один вопрос. Есть ли способ удалить альянсы из «alliances_names», если в df2 есть не все альянсы? В результате останется только совместное предприятие steam / nsoap с дубликатами и совместное предприятие watrloo / ncgc inc / nflow inc с дубликатами.
2. Спасибо! но это странно работает в наборе данных с 164000 строками. Он удаляет некоторые строки с альянсами, в которых все компании указаны в «company», я не знаю почему: ( Я заметил это, когда проверял некоторые данные вручную.
3. Не следует — логика не зависит от размера вашего фрейма данных. Могут быть ваши фактические данные (различия в написании или начальные / конечные пробелы и т. Д.).