Поэтому я выполняю упражнение из Datacamp, которое говорит вам суммировать ожидаемую продолжительность жизни по регионам из двух файлов.
Источник: https://s3.amazonaws.com/assets.datacamp.com/production/course_1650/datasets/life_expectancy.csv
Источник: https://s3.amazonaws.com/assets.datacamp.com/production/course_1650/datasets/regions.csv
# Read life_fname into a DataFrame: life
life = pd.read_csv(life_fname, index_col='Country')
# Read regions_fname into a DataFrame: regions
regions = pd.read_csv(regions_fname, index_col='Country')
# Group life by regions['region']: life_by_region
life_by_region = life.groupby(regions['region'])
print(life_by_region)
# Print the mean over the '2010' column of life_by_region
print(life_by_region['2010'].mean())
Я понимаю, что index_col делает с одним фреймворком данных, но то, что я не понимаю, - это то, как знает python, чтобы найти столбец "общего знаменателя" ["Страна"] на нескольких фреймах данных?
Я не утверждаю:
жизнь ['Страна'] == регионы ['Страна'].
Ваше подозрение верно. Pandas/Python 100% не делает вывод о том, что life['Country'] == regions['Country']
. Кто-то исправит меня, если я ошибаюсь (я не специалист по life.groupby(regions['region'])
), но когда вы указываете life.groupby(regions['region'])
, вы говорите пандам, чтобы сделать 2 основных вещи:
Во-первых: Pandas видит, что вы хотите группировать regions['region']
. Для этого он отображает все индексы для regions['region']
Series в любую группу, к которой они принадлежат.
Во- вторых: Панды принимает отображения из индексов групп и применяет их к life
индекса Dataframe.
Почему это работает? Простое совпадение. Единственная причина, по которой это работает, состоит в том, что (a) ваши Dataframes имеют одинаковую длину, и (b) ваши индексы для ваших Dataframes действительно хорошо сочетаются. Так что эта групповая операция срабатывает, но вы должны знать, что все это случайно. Если вы хотите на самом деле сделать это разумным и надежным способом, вы должны объединить два Dataframes по country
(или что-то подходящее), а затем выполнить groupby. Надеюсь это поможет.
EDIT: добавлен пример того, как правильно это сделать:
pd.merge(life, regions, how='left', left_index=True,
right_index=True).groupby('region')['2010'].mean()
It is better to do group by after merging the data frame,it works
well even index is not same.
df1 = pd.DataFrame({"Country": ['A', 'B', 'C', 'D', 'E',"F"],
"life_expectency": [60, 70, 80, 50, 100,80]})
df2 = pd.DataFrame({"Country": ['E', 'D', 'C', 'B', 'A'],
"region": ['region1', 'region1', 'region2',
'region2', 'region2']})
pd.merge(df1,df2,how="left").groupby("region")[2010].mean()
note-taken same dataframes from ALollz answer.
Хотя такая группировка может показаться опасной и случайной вначале, она, оказывается, довольно хорошо себя ведет.
Ключевым моментом здесь является то, что при передаче Series
как объекта группировки в DataFrame.groupby()
он по умолчанию выравнивает серию по индексам. Как правило, вы группируете DataFrame
одним из своих собственных столбцов, и в этом случае выравнивание по индексу практически гарантируется. Но в этом случае, поскольку оба DataFrames
имеют country
поскольку их индексные панды соответствующим образом выравнивают значения в life
с правильной region
и вычисляют среднее значение.
Два DataFrames
можно даже упорядочить по-разному и могут иметь различное количество общих элементов, и вычисления будут вести себя правильно. Следующие три примера должны проиллюстрировать этот момент:
import pandas as pd
df1 = pd.DataFrame({'Country': ['A', 'B', 'C', 'D', 'E'],
'val': [1, 2, 3, 4, 5]})
df2 = pd.DataFrame({'Country': ['E', 'D', 'C', 'B', 'A'],
'region': ['region1', 'region1', 'region2', 'region2', 'region2']})
df3 = pd.DataFrame({'Country': ['E', 'D', 'C', 'B'],
'region': ['region1', 'region1', 'region2', 'region2']})
df4 = pd.DataFrame({'Country': ['E', 'D', 'C', 'B', 'A', 'Z'],
'region': ['region1', 'region1', 'region2', 'region2', 'region2', 'region7']})
df1 = df1.set_index('Country')
df2 = df2.set_index('Country')
df3 = df3.set_index('Country')
df4 = df4.set_index('Country')
Оба DataFrames имеют одинаковые индексы и имеют одинаковую длину, но они не сортируются одинаково.
df1.groupby(df2.region).mean()
# val
#region
#region1 4.5
#region2 2.0
Поскольку серия сначала выровнена по индексу, среднее значение каждой области все еще правильно вычисляется. region1
содержит 'E'
и 'D'
которые имеют значение 4
и 5
Группировка DataFrame
короче по длине и не содержит всех стран в DataFrame
должны быть сгруппированы
df1.groupby(df3.region).mean()
# val
#region
#region1 4.5
#region2 2.5
Опять же, расчет работает правильно. 'A'
не имеет региона, поэтому он больше не включается, и среднее значение для каждого региона вычисляется правильно.
Группировка DataFrame
содержит больше групп, чем DataFrame
быть сгруппированы
df1.groupby(df3.region).mean()
# val
#region
#region1 4.5
#region2 2.0
Поскольку дополнительная группа не DataFrame
ни с чем в сгруппированном DataFrame
это не приводит к выходу.
В основном, единственное, что вызовет проблему, - это то, что индекс серии, которую вы используете для группировки, дублируется. Тогда pandas
не могут определить, как правильно выровнять значения.