tynbl.github.io

实战案例1:世界幸福指数报告分析

1. 项目描述:

世界快乐报告(英语:World Happiness Report)是联合国为衡量快乐之可持续发展方案,于网络上出版的国际调查报告。该报告由英属哥伦比亚大学、加拿大高等研究院教授约翰·F·哈利维尔(John F. Helliwell);开创“快乐经济学”为名的理查·莱亚德;哥伦比亚大学地球研究所所长及教授、前联合国秘书长潘基文的特别顾问杰佛瑞·萨克斯等人所编。

2012年4月1日,第一份世界快乐报告正式发行,成为世界首份以快乐为基础的国际调查报告,引起国际社会之间的关注。报告中介绍了世界各国快乐和痛苦的成因以及国家政策所带来的影响,其中包含来自不丹等国家的实例研究。

2013年9月,第二份世界快乐报告接续了第一年的数据。报告中的数据来自盖洛普世界民意调查。第一份世界快乐报告使用2005年至2011年的可靠数据。第二份世界快乐报告使用2005年至2012年的可靠数据,其中着重于2010年至2012年的数据。

多名经济学、心理学、调查研究和国家统计等相关领域的顶尖学者,在报告中说明了如何测定幸福,并且有效地利用在国家发展上。第二份世界快乐报告则细分有关幸福的问题,其中包含了精神疾病、幸福外在好处、道德重要性、政策影响,以及经济合作暨发展组织的连接途径等来测定主观幸福感和人类发展指数。

2. 数据集描述:

3. 项目任务:

4. 项目实现:

# 引入必要的包
import csv
import os
import numpy as np
import pandas as pd
# 指定数据集路径
dataset_path = '../data'
report_2015_datafile = os.path.join(dataset_path, '2015.csv')
report_2016_datafile = os.path.join(dataset_path, '2016.csv')
# 读入数据
def load_data(data_file):
    """
        读取数据文件,加载数据。
        返回列表,其中列表中的每个元素为一个元组,包括Country, Region, Happiness Rank和Happiness Score
    """
    data = []
    with open(data_file, 'r') as csvfile:
        data_reader = csv.DictReader(csvfile)
        for row in data_reader:
            # 取出每行数据的Country, Region, Happiness Rank和Hapiness Score,组合为一个元组放入数据列表中
            # 注意csv模块读入的数据全部为字符串类型
            data.append((row['Country'], row['Region'], 
                         row['Happiness Rank'], row['Happiness Score']))
    return data


report_2015_data = load_data(report_2015_datafile)
report_2016_data = load_data(report_2016_datafile)
# 数据预览
print('2015年报告,前10条记录预览:')
print(report_2015_data[:10])

print('2016年报告,前10条记录预览:')
print(report_2016_data[:10])
2015年报告,前10条记录预览:
[('Switzerland', 'Western Europe', '1', '7.587'), ('Iceland', 'Western Europe', '2', '7.561'), ('Denmark', 'Western Europe', '3', '7.527'), ('Norway', 'Western Europe', '4', '7.522'), ('Canada', 'North America', '5', '7.427'), ('Finland', 'Western Europe', '6', '7.406'), ('Netherlands', 'Western Europe', '7', '7.378'), ('Sweden', 'Western Europe', '8', '7.364'), ('New Zealand', 'Australia and New Zealand', '9', '7.286'), ('Australia', 'Australia and New Zealand', '10', '7.284')]
2016年报告,前10条记录预览:
[('Denmark', 'Western Europe', '1', '7.526'), ('Switzerland', 'Western Europe', '2', '7.509'), ('Iceland', 'Western Europe', '3', '7.501'), ('Norway', 'Western Europe', '4', '7.498'), ('Finland', 'Western Europe', '5', '7.413'), ('Canada', 'North America', '6', '7.404'), ('Netherlands', 'Western Europe', '7', '7.339'), ('New Zealand', 'Australia and New Zealand', '8', '7.334'), ('Australia', 'Australia and New Zealand', '9', '7.313'), ('Sweden', 'Western Europe', '10', '7.291')]

4.1 查看幸福指数分布情况

# 注意列表推导式的使用
happiness_2015_scores = [float(item[3]) for item in report_2015_data]
happiness_2016_scores = [float(item[3]) for item in report_2016_data]

# 查看数据
print('2015年报告,前10条记录幸福指数:', happiness_2015_scores[:10])
print('2016年报告,前10条记录幸福指数:', happiness_2016_scores[:10])
2015年报告,前10条记录幸福指数: [7.587, 7.561, 7.527, 7.522, 7.427, 7.406, 7.378, 7.364, 7.286, 7.284]
2016年报告,前10条记录幸福指数: [7.526, 7.509, 7.501, 7.498, 7.413, 7.404, 7.339, 7.334, 7.313, 7.291]

使用numpy.histogram查看数据的直方图分布

hist_2015, hist_edge_2015 = np.histogram(happiness_2015_scores)
hist_2016, hist_edge_2016 = np.histogram(happiness_2016_scores)

print('2015年报告,幸福指数直方图分布:{};直方图边界:{}。'.format(hist_2015, hist_edge_2015))
print('2016年报告,幸福指数直方图分布:{};直方图边界:{}。'.format(hist_2016, hist_edge_2016))
2015年报告,幸福指数直方图分布:[ 3 10 13 25 28 12 26 14 12 15];直方图边界:[ 2.839   3.3138  3.7886  4.2634  4.7382  5.213   5.6878  6.1626  6.6374
  7.1122  7.587 ]。
2016年报告,幸福指数直方图分布:[ 4 10 20 15 25 19 21 17 12 14];直方图边界:[ 2.905   3.3671  3.8292  4.2913  4.7534  5.2155  5.6776  6.1397  6.6018
  7.0639  7.526 ]。

4.2 统计分析区域的幸福指数

def get_region_happiness_scores(report_data):
    """
        获取区域包含国家的幸福指数
    """
    region_score_dict = {}
    for item in report_data:
        region = item[1]
        score = float(item[3])
        if region in region_score_dict:
            # 如果region_score_dict已经记录了该区域,则添加该区域的幸福指数到列表中
            region_score_dict[region].append(score)
        else:
            # 如果region_score_dict未记录该区域,则为该区域初始化一个空列表
            region_score_dict[region] = []
    return region_score_dict

region_2015_score_dict = get_region_happiness_scores(report_2015_data)
region_2016_score_dict = get_region_happiness_scores(report_2015_data)

# 遍历数据字典,以2015年为例
print('2015报告:')
for region, scores in region_2015_score_dict.items():
    print('{}:最大值{},最小值{},平均值{},中间值{}'.format(region,
        np.max(scores), np.min(scores), np.mean(scores), np.median(scores)))
2015报告:
Western Europe:最大值7.561,最小值4.857,平均值6.64475,中间值6.902
North America:最大值7.119,最小值7.119,平均值7.119,中间值7.119
Australia and New Zealand:最大值7.284,最小值7.284,平均值7.284,中间值7.284
Middle East and Northern Africa:最大值6.901,最小值3.006,平均值5.308421052631579,中间值5.192
Latin America and Caribbean:最大值7.187,最小值4.518,平均值6.093190476190476,中间值6.13
Southeastern Asia:最大值6.455,最小值3.819,平均值5.132375000000001,中间值5.2165
Central and Eastern Europe:最大值6.003,最小值4.218,平均值5.291071428571429,中间值5.249
Eastern Asia:最大值5.987,最小值4.874,平均值5.4918,中间值5.474
Sub-Saharan Africa:最大值5.268,最小值2.839,平均值4.170128205128205,中间值4.252
Southern Asia:最大值5.194,最小值3.575,平均值4.468833333333333,中间值4.5395

4.3 比较两年间的排名变化情况

# 将数据构建成字典,key是国家,value是其排名
# 扩展:字典推导式
country_2015_score_dict = {item[0] : int(item[2]) for item in report_2015_data}
country_2016_score_dict = {item[0] : int(item[2]) for item in report_2016_data}

# 2015年数据预览
print(country_2015_score_dict)
{'Switzerland': 1, 'Iceland': 2, 'Denmark': 3, 'Norway': 4, 'Canada': 5, 'Finland': 6, 'Netherlands': 7, 'Sweden': 8, 'New Zealand': 9, 'Australia': 10, 'Israel': 11, 'Costa Rica': 12, 'Austria': 13, 'Mexico': 14, 'United States': 15, 'Brazil': 16, 'Luxembourg': 17, 'Ireland': 18, 'Belgium': 19, 'United Arab Emirates': 20, 'United Kingdom': 21, 'Oman': 22, 'Venezuela': 23, 'Singapore': 24, 'Panama': 25, 'Germany': 26, 'Chile': 27, 'Qatar': 28, 'France': 29, 'Argentina': 30, 'Czech Republic': 31, 'Uruguay': 32, 'Colombia': 33, 'Thailand': 34, 'Saudi Arabia': 35, 'Spain': 36, 'Malta': 37, 'Taiwan': 38, 'Kuwait': 39, 'Suriname': 40, 'Trinidad and Tobago': 41, 'El Salvador': 42, 'Guatemala': 43, 'Uzbekistan': 44, 'Slovakia': 45, 'Japan': 46, 'South Korea': 47, 'Ecuador': 48, 'Bahrain': 49, 'Italy': 50, 'Bolivia': 51, 'Moldova': 52, 'Paraguay': 53, 'Kazakhstan': 54, 'Slovenia': 55, 'Lithuania': 56, 'Nicaragua': 57, 'Peru': 58, 'Belarus': 59, 'Poland': 60, 'Malaysia': 61, 'Croatia': 62, 'Libya': 63, 'Russia': 64, 'Jamaica': 65, 'North Cyprus': 66, 'Cyprus': 67, 'Algeria': 68, 'Kosovo': 69, 'Turkmenistan': 70, 'Mauritius': 71, 'Hong Kong': 72, 'Estonia': 73, 'Indonesia': 74, 'Vietnam': 75, 'Turkey': 76, 'Kyrgyzstan': 77, 'Nigeria': 78, 'Bhutan': 79, 'Azerbaijan': 80, 'Pakistan': 81, 'Jordan': 82, 'Montenegro': 82, 'China': 84, 'Zambia': 85, 'Romania': 86, 'Serbia': 87, 'Portugal': 88, 'Latvia': 89, 'Philippines': 90, 'Somaliland region': 91, 'Morocco': 92, 'Macedonia': 93, 'Mozambique': 94, 'Albania': 95, 'Bosnia and Herzegovina': 96, 'Lesotho': 97, 'Dominican Republic': 98, 'Laos': 99, 'Mongolia': 100, 'Swaziland': 101, 'Greece': 102, 'Lebanon': 103, 'Hungary': 104, 'Honduras': 105, 'Tajikistan': 106, 'Tunisia': 107, 'Palestinian Territories': 108, 'Bangladesh': 109, 'Iran': 110, 'Ukraine': 111, 'Iraq': 112, 'South Africa': 113, 'Ghana': 114, 'Zimbabwe': 115, 'Liberia': 116, 'India': 117, 'Sudan': 118, 'Haiti': 119, 'Congo (Kinshasa)': 120, 'Nepal': 121, 'Ethiopia': 122, 'Sierra Leone': 123, 'Mauritania': 124, 'Kenya': 125, 'Djibouti': 126, 'Armenia': 127, 'Botswana': 128, 'Myanmar': 129, 'Georgia': 130, 'Malawi': 131, 'Sri Lanka': 132, 'Cameroon': 133, 'Bulgaria': 134, 'Egypt': 135, 'Yemen': 136, 'Angola': 137, 'Mali': 138, 'Congo (Brazzaville)': 139, 'Comoros': 140, 'Uganda': 141, 'Senegal': 142, 'Gabon': 143, 'Niger': 144, 'Cambodia': 145, 'Tanzania': 146, 'Madagascar': 147, 'Central African Republic': 148, 'Chad': 149, 'Guinea': 150, 'Ivory Coast': 151, 'Burkina Faso': 152, 'Afghanistan': 153, 'Rwanda': 154, 'Benin': 155, 'Syria': 156, 'Burundi': 157, 'Togo': 158}
# 将数据转换为Series
ser_2015 = pd.Series(country_2015_score_dict)
ser_2016 = pd.Series(country_2016_score_dict)

print('2015年,数据预览:')
print(ser_2015.head())

print('2016年,数据预览:')
print(ser_2016.head())
2015年,数据预览:
Afghanistan    153
Albania         95
Algeria         68
Angola         137
Argentina       30
dtype: int64
2016年,数据预览:
Afghanistan    154
Albania        109
Algeria         38
Angola         141
Argentina       26
dtype: int64
# 将两年的记录相减,即得出排名变化情况
# 注意Series在进行计算时,是按照index的顺序进行计算的,所以不需要担心顺序问题
# NaN表示某一年的记录缺失,无法计算
ser_change = ser_2016 - ser_2015
print('2015-2016排名变化:')
print(ser_change)
2015-2016排名变化:
Afghanistan                  1.0
Albania                     14.0
Algeria                    -30.0
Angola                       4.0
Argentina                   -4.0
Armenia                     -6.0
Australia                   -1.0
Austria                     -1.0
Azerbaijan                   1.0
Bahrain                     -7.0
Bangladesh                   1.0
Belarus                      2.0
Belgium                     -1.0
Belize                       NaN
Benin                       -2.0
Bhutan                       5.0
Bolivia                      8.0
Bosnia and Herzegovina      -9.0
Botswana                     9.0
Brazil                       1.0
Bulgaria                    -5.0
Burkina Faso                -7.0
Burundi                      0.0
Cambodia                    -5.0
Cameroon                   -19.0
Canada                       1.0
Central African Republic     NaN
Chad                        -5.0
Chile                       -3.0
China                       -1.0
                            ... 
South Sudan                  NaN
Spain                        1.0
Sri Lanka                  -15.0
Sudan                       15.0
Suriname                     0.0
Swaziland                    NaN
Sweden                       2.0
Switzerland                  1.0
Syria                        0.0
Taiwan                      -4.0
Tajikistan                  -6.0
Tanzania                     3.0
Thailand                    -1.0
Togo                        -3.0
Trinidad and Tobago          2.0
Tunisia                     -9.0
Turkey                       2.0
Turkmenistan                -5.0
Uganda                       4.0
Ukraine                     12.0
United Arab Emirates         8.0
United Kingdom               2.0
United States               -2.0
Uruguay                     -3.0
Uzbekistan                   5.0
Venezuela                   21.0
Vietnam                     21.0
Yemen                       11.0
Zambia                      21.0
Zimbabwe                    16.0
Length: 164, dtype: float64
# 可查看某个国家的排名变化
print('中国的排名变化:')
print(ser_change['China'])
中国的排名变化:
-1.0
# 查看上升最快的国家
print('2015-2016幸福指数上升最快的国家', ser_change.argmax())
# 查看下降最快的国家
print('2015-2016幸福指数下降最快的国家', ser_change.argmin())
2015-2016幸福指数上升最快的国家 Liberia
2015-2016幸福指数下降最快的国家 Algeria

5. 项目总结