#python #pandas #merge
#python #pandas #слияние
Вопрос:
Я уже давно борюсь со следующей проблемой и был бы признателен за любую помощь.
Я хочу объединить df1 и df2 в «стране».
df1.head()
--- ----------------- ------------ ------------------------------------------------- ---------------------------------- ------------------------- ----------- ------------ ----------- ------------ ----------------- -----------------
| | loan_theme_id | partner_id | field_partner_name | loan_theme_type | location_name | lat | lon | rural_pct | city | region | country |
--- ----------------- ------------ ------------------------------------------------- ---------------------------------- ------------------------- ----------- ------------ ----------- ------------ ----------------- -----------------
| 0 | a1050000000wDrQ | 175 | Koret Israel Economic Development Funds (KIEDF) | Underserved | Abu Sanaan, Israel | 32.958030 | 35.171969 | 0.0 | Abu Sanaan | Israel | Israel |
| 1 | a1050000007S5Kt | 485 | Building Markets | SME | Yangon, Myanmar (Burma) | 16.866069 | 96.195132 | NaN | Yangon | Myanmar (Burma) | Myanmar (Burma) |
| 2 | a1050000002YCWe | 369 | AsociaciÍ_n Chajulense de Mujeres (ACMUV) | Artisan | Chajul, Guatemala | 15.483483 | -91.037070 | NaN | Chajul | Guatemala | Guatemala |
| 3 | a1050000007qJuI | 77 | Al Majmoua | Vulnerable Populations (Syrian)2 | Aley, Lebanon | 33.810086 | 35.597326 | 43.0 | Aley | Lebanon | Lebanon |
| 4 | a1050000006FnC9 | 357 | Alivio Capital | Imagen Dental | Matamoros,Tamps, Mexico | 25.869029 | -97.502738 | 3.0 | Matamoros | Tamps | Mexico |
--- ----------------- ------------ ------------------------------------------------- ---------------------------------- ------------------------- ----------- ------------ ----------- ------------ ----------------- -----------------
Вот типы столбцов для df1
Int64Index: 100 entries, 108 to 549
Data columns (total 11 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 loan_theme_id 100 non-null category
1 partner_id 100 non-null category
2 field_partner_name 100 non-null string
3 loan_theme_type 100 non-null category
4 location_name 100 non-null string
5 lat 100 non-null float64
6 lon 100 non-null float64
7 rural_pct 79 non-null float64
8 city 100 non-null string
9 region 100 non-null string
10 country 100 non-null string
dtypes: category(3), float64(3), string(5)
memory usage: 19.2 KB
df2.head()
--- ------------- ------------------------- ----------
| | country | world_region | MPI |
--- ------------- ------------------------- ----------
| 0 | Afghanistan | South Asia | 0.309853 |
| 1 | Albania | Europe and Central Asia | NaN |
| 2 | Algeria | Arab States | NaN |
| 3 | Armenia | Europe and Central Asia | NaN |
| 4 | Azerbaijan | Europe and Central Asia | NaN |
--- ------------- ------------------------- ----------
Типы столбцов:
<class 'pandas.core.frame.DataFrame'>
Int64Index: 102 entries, 0 to 101
Data columns (total 3 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 country 102 non-null string
1 world_region 102 non-null object
2 MPI 78 non-null float64
dtypes: float64(1), object(1), string(1)
memory usage: 3.2 KB
Обеспечение хотя бы некоторого перекрытия:
display(df2[(df2.country == 'Guatemala')])
---- ----------- ----------------------------- ----------
| | country | world_region | MPI |
---- ----------- ----------------------------- ----------
| 34 | Guatemala | Latin America and Caribbean | 0.113957 |
---- ----------- ----------------------------- ----------
Слияние:
df3 = pd.merge(df1, df2, on='country', how='left')
df3.head()
--- ----------------- ------------ ------------------------------------------------- ---------------------------------- ------------------------- ----------- ------------ ----------- ------------ ----------------- ----------------- -------------- -----
| | loan_theme_id | partner_id | field_partner_name | loan_theme_type | location_name | lat | lon | rural_pct | city | region | country | world_region | MPI |
--- ----------------- ------------ ------------------------------------------------- ---------------------------------- ------------------------- ----------- ------------ ----------- ------------ ----------------- ----------------- -------------- -----
| 0 | a1050000000wDrQ | 175 | Koret Israel Economic Development Funds (KIEDF) | Underserved | Abu Sanaan, Israel | 32.958030 | 35.171969 | 0.0 | Abu Sanaan | Israel | Israel | NaN | NaN |
| 1 | a1050000007S5Kt | 485 | Building Markets | SME | Yangon, Myanmar (Burma) | 16.866069 | 96.195132 | NaN | Yangon | Myanmar (Burma) | Myanmar (Burma) | NaN | NaN |
| 2 | a1050000002YCWe | 369 | AsociaciÍ_n Chajulense de Mujeres (ACMUV) | Artisan | Chajul, Guatemala | 15.483483 | -91.037070 | NaN | Chajul | Guatemala | Guatemala | NaN | NaN |
| 3 | a1050000007qJuI | 77 | Al Majmoua | Vulnerable Populations (Syrian)2 | Aley, Lebanon | 33.810086 | 35.597326 | 43.0 | Aley | Lebanon | Lebanon | NaN | NaN |
| 4 | a1050000006FnC9 | 357 | Alivio Capital | Imagen Dental | Matamoros,Tamps, Mexico | 25.869029 | -97.502738 | 3.0 | Matamoros | Tamps | Mexico | NaN | NaN |
--- ----------------- ------------ ------------------------------------------------- ---------------------------------- ------------------------- ----------- ------------ ----------- ------------ ----------------- ----------------- -------------- -----
Типы столбцов
<class 'pandas.core.frame.DataFrame'>
Int64Index: 100 entries, 0 to 99
Data columns (total 13 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 loan_theme_id 100 non-null category
1 partner_id 100 non-null category
2 field_partner_name 100 non-null string
3 loan_theme_type 100 non-null category
4 location_name 100 non-null string
5 lat 100 non-null float64
6 lon 100 non-null float64
7 rural_pct 79 non-null float64
8 city 100 non-null string
9 region 100 non-null string
10 country 100 non-null string
11 world_region 0 non-null object
12 MPI 0 non-null float64
Я действительно не понимаю, почему результат NaN в world_region и MPI. Я убедился, что в df1 и df2 в country нет NAN и что есть хотя бы какое-то перекрытие. Также совпадают типы столбцов.
Редактировать: благодаря Полу я попытался получить информацию, например, о «Гватемале» в df1. В приведенной выше таблице мы видим, что он действительно присутствует в df1. Однако при запуске display(df2[(df2.country == 'Guatemala')])
возвращается пустой фрейм данных. Итак, я попытался запустить display(df2[(df2.country == ‘Гватемала’)]) с дополнительным пробелом в начале, и теперь мы получаем некоторые результаты:
--- ----------------- ------------ ------------------------------------------- ----------------- ------------------- ----------- ----------- ----------- -------- ----------- -----------
| | loan_theme_id | partner_id | field_partner_name | loan_theme_type | location_name | lat | lon | rural_pct | city | region | country |
--- ----------------- ------------ ------------------------------------------- ----------------- ------------------- ----------- ----------- ----------- -------- ----------- -----------
| 2 | a1050000002YCWe | 369 | AsociaciÍ_n Chajulense de Mujeres (ACMUV) | Artisan | Chajul, Guatemala | 15.483483 | -91.03707 | NaN | Chajul | Guatemala | Guatemala |
--- ----------------- ------------ ------------------------------------------- ----------------- ------------------- ----------- ----------- ----------- -------- ----------- -----------
Что приводит к вопросу, есть ли в pandas функция для проверки наличия пробелов в столбце df?
Ответ №1:
Вы выполняете левое соединение, указанное left
ключевым словом в команде слияния. Это означает, что если в правом фрейме данных нет страны, которую имеет строка в левом, вы получите NaNs.
Для получения дополнительной информации о типах соединений и, в частности, о левых соединениях, см., Например, Здесь: https://www.w3schools.com/sql/sql_join_left.asp
Редактировать:
Это потому, что в одном из фреймов данных есть дополнительное пустое пространство вокруг строки. Перед объединением вы можете удалить пробелы с trim()
помощью функции.
Комментарии:
1. Привет, Пол, спасибо за твой ответ. Но у df2 есть «Гватемала», так как у df1 также есть «Гватемала» в строке 3. Разве объединение не должно работать, по крайней мере, в этом случае? Еще раз спасибо за ваше время и быстрый ответ!
2. Ты прав. В таком случае это должно сработать. Вы уверены, что в df1 нет лишнего места
Guatemala
или какой-либо другой опечатки?display(df1[(df1.country == 'Guatemala')])
Возвращает строку?3. Привет, Пол, спасибо! Вы выдвинули правильную идею. Знаете ли вы функцию, с помощью которой я мог бы лучше проверить это в будущем?
4. может быть, вы можете удалить начальные и конечные пробелы с помощью
trim
функции, а может быть, и пользователя.lower()
, чтобы иметь все в нижнем регистре и больше не беспокоиться о капитализации. Однако это не помогает по сравнению с другими опечатками5. Эй, Пол, спасибо, я попробую. Если вы хотите, опубликуйте еще одно предложение о пустом дополнительном пространстве, чтобы я мог пометить его как правильный ответ.