討論問題:
一摔刁、很多媒體報(bào)道美國在過去一些年間貧富差距擴(kuò)大。這里我們分析全球數(shù)據(jù)净蚤,運(yùn)用數(shù)據(jù)分析全球各個(gè)州之間在過去20年間的貧富差距是擴(kuò)大钥组,減小還是維持不變。
二今瀑、以亞洲與南美數(shù)據(jù)為例分析程梦,如果A組的平均值大于B組,是否說明最大值在A組中
1橘荠、首先屿附,將國家和地區(qū)數(shù)據(jù)在Github上取下來:
url = "https://raw.githubusercontent.com/cs109/2014_data/master/countries.csv"
s = StringIO.StringIO(requests.get(url).content)
countries = pd.read_csv(s)
print countries.head()
Country Region
0 Algeria AFRICA
1 Angola AFRICA
2 Benin AFRICA
3 Botswana AFRICA
4 Burkina AFRICA
然后將國家的人均收入數(shù)據(jù)從https://www.gapminder.org/data/documentation/gd001/這個(gè)網(wǎng)站上取下來
income = pd.read_excel('.../indicator gapminder gdp_per_capita_ppp.xlsx',sheetname = "Data")
print income.head()
GDP per capita 1800 1801 1802 1803 1804 1805
0 Abkhazia NaN NaN NaN NaN NaN NaN
1 Afghanistan 603.0 603.0 603.0 603.0 603.0 603.0
2 Akrotiri and Dhekelia NaN NaN NaN NaN NaN NaN
3 Albania 667.0 667.0 668.0 668.0 668.0 668.0
4 Algeria 716.0 716.0 717.0 718.0 719.0 720.0
有些國家沒有數(shù)據(jù),刪除缺失項(xiàng)
income = income.dropna(how='all')
我們想要畫出某年各個(gè)國家的人均收入分布圖,分布圖用直方圖來表示是最合適的,這里將年份作為行名更容易畫各年的直方圖
income.index=income[income.columns[0]] # 國家作為序號
income = income.drop(income.columns[0], axis = 1)
income.columns = map(lambda x: int(x), income.columns) # 將列名中的年份數(shù)據(jù)轉(zhuǎn)為int類型哥童,為了直接取年份
income = income.transpose()#轉(zhuǎn)置
print income.head()
GDP per capita Afghanistan Albania Algeria Andorra Angola \
1800 603.0 667.0 716.0 1197.0 618.0
1801 603.0 667.0 716.0 1199.0 620.0
1802 603.0 668.0 717.0 1201.0 623.0
1803 603.0 668.0 718.0 1204.0 626.0
1804 603.0 668.0 719.0 1206.0 628.0
接下來畫直方圖:
year = 2000
plt.hist(income.ix[year].values, bins = 20)
plt.title('Year: %i' % year)
plt.xlabel('人均收入')
plt.ylabel('頻數(shù)')
plt.show()
可以看出人均一萬美金以下的國家最多挺份,各個(gè)國家之間的貧富差距相當(dāng)大,那1萬美金以下究竟是怎么分布的看不出來贮懈,將收入取log則能區(qū)分出來:
plt.hist(np.log10(income.ix[year].dropna().values), bins = 20)
plt.title('Year: %i' % year)
plt.xlabel('人均收入 (log10)')
plt.ylabel('頻數(shù)')
plt.show()
可以看出2000年時(shí)人均10000美金的國家是最多的匀泊,人均一萬美金以下的分布也較廣影暴,還有人均幾百美金的
接下來看各州之間的貧富差距:
2、將Country表格與income表格合并探赫,觀察兩個(gè)表格可以看出共同的參數(shù)是國家名型宙,所以以這個(gè)為主鍵進(jìn)行合并
def mergeByYear(year):
#取出收入數(shù)據(jù)
data = pd.DataFrame(income.ix[year].values, columns=['Income'])
# 拿到income的列名,作為新dataframe的Country列
data['Country'] = income.columns
joined = pd.merge(data, countries, how="inner", on=['Country'])
return joined
print mergeByYear(2000).head()
Income Country Region
0 962.0 Afghanistan ASIA
1 5305.0 Albania EUROPE
2 9885.0 Algeria AFRICA
3 31662.0 Andorra EUROPE
4 3387.0 Angola AFRICA
3伦吠、畫出各州的人均收入分布,這里采用箱形圖來表現(xiàn)妆兑,箱形圖可以表示數(shù)據(jù)的多種特征,如下圖所示:
可以看出亞洲和非洲人均收入的趨勢是向上的毛仪,亞洲相比上升更多搁嗓,其他州則基本保持不變。同時(shí)可以看出非洲和亞洲的奇異值相比較多箱靴,并且箱型圖越來越長腺逛,說明亞洲和非洲各個(gè)國家之間的貧富差距較大,這種差距從20世紀(jì)60年代持續(xù)至今衡怀。
接下來討論問題二:
1棍矛、如果有兩組數(shù)據(jù)X和Y,都大致服從正態(tài)分布抛杨,X和Y的標(biāo)準(zhǔn)差都為1够委,但是X的均值大于Y的均值,計(jì)算Pr(X > a)/Pr(Y > a) 怖现。
列出該表達(dá)式的函數(shù):
diff是X的均值茁帽,Y的均值為0
def ratioNormals(diff,a):
X = scipy.stats.norm(loc = diff,scale = 1)
Y = scipy.stats.norm(loc = 0,scale = 1)
return X.sf(a)/Y.sf(a) #sf是生存函數(shù),即求X>a的概率
用不同的均值差來計(jì)算概率比值:
diffs = np.linspace(0,5,50)
aa = range(2,6)
for a in aa:
ratios = [ratioNormals(diff, a) for diff in diffs]
plt.plot(diffs,ratios)
plt.legend(["a={}".format(a) for a in aa], loc=0);
plt.xlabel('Diff');
plt.ylabel('Pr(X>a) / Pr(Y>a)');
plt.title('不同差值下Pr(X>a)與Pr(Y>a)的概率比');
plt.yscale('log')
plt.show()
可以看出屈嗤,在正太分布下潘拨,當(dāng)X的均值大于Y時(shí),Pr(X>a)>Pr(Y>a),并且差值越大饶号,兩者之間的差距也越大铁追。
2、考慮亞洲和南美的人均收入分布讨韭,計(jì)算這兩個(gè)州的人均收入脂信,哪個(gè)州的人均收入更多
利用mergeByYear函數(shù)拿到地區(qū)癣蟋、國家透硝、收入的dataframe,按照地區(qū)分組聚合疯搅,計(jì)算平均收入濒生,可以看出亞洲的平均收入遠(yuǎn)大于南美。
merged = mergeByYear(2012).groupby('Region', as_index=False).mean()
merged = merged.loc[(merged.Region == "ASIA") | (merged.Region == "SOUTH AMERICA")]
merged.Income = np.round(merged.Income, 2)#保留小數(shù)點(diǎn)兩位
print merged
Region Income
1 ASIA 23500.43
5 SOUTH AMERICA 13015.75
3幔欧、那接下來算一下人居收入大于10000美金的國家占所在州的比例罪治,丽声,再次看一下上面的結(jié)論是否正確。構(gòu)造一個(gè)計(jì)算國家比例的函數(shù):
def ratioCountries(groupedData, a):
#下面key指的是Region觉义,group指代的是key所對應(yīng)的分組雁社,必須要有key指定才能找到分組信息,這里求得是各州中人均收入大于10000美金的國家占所在州國家的比例
prop = [len(group.Income[group.Income >= a]) / float(len(group.Income.dropna())) for key, group in groupedData]
z = pd.DataFrame(groupedData.mean().index, columns = ['Region'])
z['Mean'] = np.round(groupedData.mean().values,2)
z['P(X > %g)' % a] = np.round(prop, 4)
return z
df = mergeByYear(2012).groupby('Region')
df_ratio = ratioCountries(df, 1e4)
print df_ratio
Region Mean P(X > 10000)
0 AFRICA 5601.22 0.2000
1 ASIA 23500.43 0.5676
2 EUROPE 30738.19 0.8571
3 NORTH AMERICA 16036.65 0.6500
4 OCEANIA 10481.15 0.3077
5 SOUTH AMERICA 13015.75 0.7500
把南美和亞洲提取出來:
df_ratio = df_ratio[(df_ratio.Region == 'ASIA') | (df_ratio.Region == 'SOUTH AMERICA')]
print df_ratio
Region Mean P(X > 10000)
1 ASIA 23500.43 0.5676
5 SOUTH AMERICA 13015.75 0.7500
可以看出人均大于10000美金的國家在所在州所占比例晒骇,亞洲小于南美霉撵,這與上面的結(jié)論不一致。
4洪囤、上面可以看出亞洲國家之間的貧富差距有多大徒坡,接下來考慮一個(gè)問題,如果考慮各國人口數(shù)量瘤缩,那人均收入是否會(huì)發(fā)生改變呢
比如我國和日本喇完,我國的人均GDP8000美金,日本人均GDP35000美金剥啤,按照上面的算法锦溪,兩國人均收入(8000+32000)/2,我國人均收入瞬間提升到20000美金府怯。如果考慮兩國人口呢海洼,假設(shè)中日是一個(gè)國家,中國人口14億富腊,日本1億3000萬坏逢,那平均收入的計(jì)算方法為:
N為人口耿币,I為本國的人均收入葛峻,則上述中日兩國修正后的人均收入為(800014+320001.3)/(14+1.3)≈10000
如此看來落午,計(jì)算了各國人口窟她,這個(gè)平均值才能代表亞洲的真實(shí)水平存谎,那接下來修正一下這個(gè)數(shù)據(jù)开泽。這里可以將上述表達(dá)式進(jìn)行拆分烦周,只需要求出各國總收入除以整個(gè)州的人口做粤,然后求和便能求出平均收入羊异。
首先導(dǎo)入人口數(shù)據(jù)事秀,并對其進(jìn)行預(yù)處理:
#首先導(dǎo)入人口數(shù)據(jù)
population = pd.read_excel('.../indicator_total population with projections.xlsx',sheetname = "Data")
print population.head()
Total population 1086 1100 1290 1300 1348 1349 1351 1377 \
0 Abkhazia NaN NaN NaN NaN NaN NaN NaN NaN
1 Afghanistan NaN NaN NaN NaN NaN NaN NaN NaN
2 Akrotiri and Dhekelia NaN NaN NaN NaN NaN NaN NaN NaN
3 Albania NaN NaN NaN NaN NaN NaN NaN NaN
4 Algeria NaN NaN NaN NaN NaN NaN NaN NaN
1413 ... 2006 2007 2008 2009 \
0 NaN ... NaN NaN NaN NaN
1 NaN ... 28420974.0 29145841.0 29839994.0 30577756.0
2 NaN ... NaN NaN 15700.0 NaN
3 NaN ... 3156607.0 3169665.0 3181397.0 3192723.0
4 NaN ... 33391954.0 33906605.0 34428028.0 34950168.0
刪除全部是NAN的國家,按照上面的方法將數(shù)據(jù)進(jìn)行處理,方便下面進(jìn)行分組聚合野舶。
population = population.dropna(how='all')
population = population.rename(columns = {'Total population':'Country'})#重命名
#把國家列設(shè)為index
population.index=population[population.columns[0]]
population = population.drop(population.columns[0], axis = 1)
population.columns = map(lambda x: int(x), population.columns)#將年份改為int類型
population = population.transpose()
接下來我們想把人口數(shù)據(jù)這個(gè)表格與mergeByYear這個(gè)包含人均收入易迹,國家,地區(qū)的表格進(jìn)行合并.
#將其與income,國家平道,地區(qū)按照國家這個(gè)主鍵進(jìn)行合并
def mergeByYearWithPop(year):
merged_df = mergeByYear(year)
pop_df = pd.DataFrame(population.ix[year].values, columns=['Population'])
pop_df['Country'] = population.columns
joined = pd.merge(merged_df,pop_df,how="inner", on=['Country'])
#按照剛才的分析求調(diào)整后的收入,再定義一個(gè)函數(shù),這里傳入的是按地區(qū)分割的groupby對象
def func(df):
totlePop = df.sum()['Population']
df['AdjustedIncome'] = df.Income * df.Population / float(totlePop)
df.AdjustedIncome = np.round(df.AdjustedIncome, 2)
return df
return joined.groupby('Region').apply(func)
print mergeByYearWithPop(2012).head()
Income Country Region Population AdjustedIncome
0 1893.0 Afghanistan ASIA 33397058.0 15.66
1 9811.0 Albania EUROPE 3227373.0 53.43
2 12779.0 Algeria AFRICA 36485828.0 489.77
3 41926.0 Andorra EUROPE 87518.0 6.19
4 7230.0 Angola AFRICA 20162517.0 153.13
得到這個(gè)dataframe后睹欲,將最后一列按照Region求和便能得出調(diào)整后的平均收入,接下來求按國家計(jì)算的平均收入和考慮人口數(shù)量的平均收入
mergeWithPop_df = mergeByYearWithPop(2012).groupby('Region').sum()
df1 = mergeByYear(2012).groupby('Region').mean()
mergeWithPop_df.Income = mergeByYear(2012).groupby('Region').mean().Income
mergeWithPop_df = mergeWithPop_df.ix[['ASIA', 'SOUTH AMERICA']]
print mergeWithPop_df
Income Population AdjustedIncome
Region
ASIA 23500.432432 4.036626e+09 9717.54
SOUTH AMERICA 13015.750000 4.005576e+08 14551.71
這里可以看出,亞洲在調(diào)整前的平均收入大于南美,而當(dāng)考慮了人口后窘疮,平均收入小于南美袋哼。
綜上所述,如果A與B都服從正太分布闸衫,那當(dāng)A的平均值大于B時(shí)涛贯,Pr(X>a)>Pr(Y>a),而當(dāng)討論兩個(gè)州人均收入大于10000美金的國家所占比例時(shí)得出了相反的結(jié)論蔚出,這是因?yàn)閲业娜司杖氩蛔裱植肌?br>
最后考慮了各國的總?cè)丝谝呗瑢⒅萑司杖脒M(jìn)行了調(diào)整,得出在調(diào)整前亞洲的人均收入大于南美身冬,然后調(diào)整后反而小了衅胀,這說明亞洲國家之間的貧富差距相當(dāng)大,太多奇異值使得按照國家計(jì)算時(shí)與按照人口計(jì)算時(shí)偏差太大酥筝,而南美各國間的貧富差距較小滚躯,兩個(gè)數(shù)據(jù)之間差距不太大。