Я работаю с базой данных international_education
из набора данных world_bank_intl_education
bigquery-public-data
.
FIELDS
country_name
country_code
indicator_name
indicator_code
value
year
Моя цель - построить линейный график со странами, которые имели наибольшее и Наименьшее изменение в росте населения (годовой процент) (одно из значений indicator_name
).
Я сделал это ниже, используя два раздела, определяя первое и последнее значения года по каждой стране, но я груб на моем SQL и мне интересно, есть ли способ оптимизировать эту формулу.
query = """
WITH differences AS
(
SELECT country_name, year, value,
FIRST_VALUE(value)
OVER (
PARTITION BY country_name
ORDER BY year
RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
) AS small_value,
LAST_VALUE(value)
OVER (
PARTITION BY country_name
ORDER BY year
RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
) AS large_value
FROM `bigquery-public-data.world_bank_intl_education.international_education`
WHERE indicator_name = 'Population growth (annual %)'
ORDER BY year
)
SELECT country_name, year, (large_value-small_value) AS total_range, value
FROM differences
ORDER BY total_range
"""
Преобразовать в pandas dataframe.
df= wbed.query_to_pandas_safe(query)
df.head(10)
Результирующая таблица.
country_name year total_range value
0 United Arab Emirates 1970 -13.195183 14.446942
1 United Arab Emirates 1971 -13.195183 16.881671
2 United Arab Emirates 1972 -13.195183 17.689814
3 United Arab Emirates 1973 -13.195183 17.695296
4 United Arab Emirates 1974 -13.195183 17.125615
5 United Arab Emirates 1975 -13.195183 16.211873
6 United Arab Emirates 1976 -13.195183 15.450884
7 United Arab Emirates 1977 -13.195183 14.530119
8 United Arab Emirates 1978 -13.195183 13.033461
9 United Arab Emirates 1979 -13.195183 11.071306
Затем я бы нарисовал это с python следующим образом.
all_countries = df.groupby('country_name', as_index=False).max().sort_values(by='total_range').country_name.values
countries = np.concatenate((all_countries[:3], all_countries[-4:]))
plt.figure(figsize=(16, 8))
sns.lineplot(x='year',y='value', data=df[df.country_name.isin(countries)], hue='country_name')