Day8-綜合作業1(DataWhale)

liying_tt發表於2021-01-01
import numpy as np
import pandas as pd
import math

任務1:企業收入的多樣性

一個企業的產業收入多樣性可以仿照資訊熵的概念來定義收入熵指標:

在這裡插入圖片描述


其中 p(x)是企業該年某產業收入額佔該年所有產業總收入的比重。在company.csv中存有需要計算的企業和年份,在company_data.csv中存有企業、各類收入額和收入年份的資訊。現請利用後一張表中的資料,在前一張表中增加一列表示該公司該年份的收入熵指標I

思路

1.將company_data錶轉換位包含證券程式碼(需轉換)、日期(年)、熵值的表

2.證券編碼需要去除"#"後轉換為INT型

3.日期取年

4.按照年分組彙總資料,求出總計,再將彙總資料與分類資料進行求值

一定要注意將小於0的資料排除乾淨

df_com = pd.read_csv('練習題資料/Company.csv')
print(df_com.dtypes)
df_com.head(2)
證券程式碼    object
日期       int64
dtype: object
證券程式碼日期
0#0000072014
1#0004032015
df_com_data = pd.read_csv('練習題資料/Company_data.csv')
df_com_data.head(2)
證券程式碼日期收入型別收入額
012008/12/3111.084218e+10
112008/12/3121.259789e+10

1.首先將資料的日期轉換為年,之前檢視的時候以為日期列儲存的是日期型別,後來發現儲存的是字串,只需要擷取前四位即可。

A = list(df_com_data['日期'])
A = [i[:4] for i in A]
df_com_data['日期'] = A
df_com_data.head(2)
證券程式碼日期收入型別收入額
01200811.084218e+10
11200821.259789e+10

2.將證券程式碼向前補0並加上"#",由於我們儲存的證券程式碼是INT型,需要轉為str之後再使用zfill填充0

B = df_com_data['證券程式碼']
B = ["#"+str(i).zfill(6) for i in B]
df_com_data['證券程式碼'] = B
df_com_data = df_com_data[df_com_data['收入額']>0]
df_com_data.head(2)
證券程式碼日期收入型別收入額
0#000001200811.084218e+10
1#000001200821.259789e+10

3.求出依據證券程式碼,日期分組後的收入額的總和,並且需要檢視是否有負值的收入額,作為異常值清除掉。此處因為在groupby的時候會將列名作為索引,因此使用了ax_index=False,方便之後排除異常值

gb_data = df_com_data.groupby(['證券程式碼','日期'],as_index=False)['收入額'].sum()
gb_data = gb_data.rename(columns={"收入額":"收入總額"})
gb_data.head(2)
證券程式碼日期收入總額
0#00000120087.402176e+10
1#00000120094.771900e+10

4.現在我們將得到的最終聚合資料與company_data進行拼接,之後求得p(i)的值

def Pi(x):
    Income = x['收入額']
    Income_ALL = x['收入總額']
    Pi_value = Income/Income_ALL
    return Pi_value.sum()
merge_data = df_com_data.merge(gb_data, left_on=['證券程式碼','日期'], right_on=['證券程式碼','日期'], how='left')
com_gb = merge_data.groupby(['證券程式碼','日期','收入型別'])[['收入額','收入總額']]
com_gb.apply(Pi)
com_gb = pd.DataFrame(com_gb.apply(Pi))
com_gb1 = com_gb.reset_index()
com_gb1 = com_gb.rename(columns = {0:'P'})
com_gb1['logP'] = com_gb1.apply(lambda x : math.log(x['P'],2) ,axis=1)
com_gb1['P*logP'] = com_gb1.apply(lambda x : x['P']*x['logP'] ,axis=1)

5.將com_gb中去掉型別,按照證券編號、日期,求得我們想要的I值,最後用merge將值拼入df_com中

com_gb2 = com_gb1.groupby(['證券程式碼','日期'])['P*logP'].sum()
com_gb3 = pd.DataFrame(com_gb2) 
com_gb3 = com_gb3.reset_index()
com_gb3 = com_gb3.rename(columns = {'P*logP':'I'})
com_gb3['日期'] = com_gb3['日期'].astype(int) #一定要賦值
com_gb3.head()
com_gb3.dtypes
證券程式碼     object
日期        int32
I       float64
dtype: object

注意:此處我遇到了一個問題:兩張表中的日期的型別不一致,所以需要將日期型別轉換為一致才能使用merge

com_data = df_com.merge(com_gb3, on = ['證券程式碼','日期'], how='left')
com_data.head()
證券程式碼日期I
0#0000072014-4.429740
1#0004032015-4.025963
2#0004082016-4.066295
3#0004082017NaN
4#0004262015-4.449655

任務2:組隊學習資訊表的變換

請把組隊學習的隊伍資訊表變換為如下形態,其中“是否隊長”一列取1表示隊長,否則為0

在這裡插入圖片描述

1.通過read_excel讀取資料,並觀察資料與目標資料的差異,發現我們源資料擁有多列的編號和名稱,我們需要將編號和名稱轉換位列,保留隊伍名稱,對於沒有存值的編號和暱稱,我們需要將他們去除

df = pd.read_excel('練習題資料/組隊資訊彙總表(Pandas).xlsx')
df.head(2)
所在群隊伍名稱隊長編號隊長_群暱稱隊員1 編號隊員_群暱稱隊員2 編號隊員_群暱稱.1隊員3 編號隊員_群暱稱.2...隊員6 編號隊員_群暱稱.5隊員7 編號隊員_群暱稱.6隊員8 編號隊員_群暱稱.7隊員9 編號隊員_群暱稱.8隊員10編號隊員_群暱稱.9
0Pandas資料分析你說的都對隊5山楓葉紛飛67.0安慕希8.0信仰...NaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
1Pandas資料分析熊貓人175魚呲呲44Heaven37.0呂青50.0餘柳成蔭...25.0Never say never55.0K120.0Y.28.0X.Y.Q151.0swrong

2 rows × 24 columns

colum = ['所在群','隊伍名稱','編號-0','暱稱-0','編號-1','暱稱-1','編號-2','暱稱-2','編號-3','暱稱-3','編號-4','暱稱-4','編號-5','暱稱-5','編號-6','暱稱-6','編號-7','暱稱-7','編號-8','暱稱-8','編號-9','暱稱-9','編號-10','暱稱-10']
df.columns=colum
df.head(2)
所在群隊伍名稱編號-0暱稱-0編號-1暱稱-1編號-2暱稱-2編號-3暱稱-3...編號-6暱稱-6編號-7暱稱-7編號-8暱稱-8編號-9暱稱-9編號-10暱稱-10
0Pandas資料分析你說的都對隊5山楓葉紛飛67.0安慕希8.0信仰...NaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
1Pandas資料分析熊貓人175魚呲呲44Heaven37.0呂青50.0餘柳成蔭...25.0Never say never55.0K120.0Y.28.0X.Y.Q151.0swrong

2 rows × 24 columns

2.多列轉行,我們考慮使用wide_to_long,先對列名進行整理,最後再將多餘資料進行刪除處理。這個過程中編號第一次轉換的是float型,需要將他轉換為Int型,這裡使用astype; 在進行是否為隊長的匹配的時候,注意一定要將取出來的值轉換為list

df1 = pd.wide_to_long(df,
               stubnames=['編號','暱稱'],
               i = ['所在群','隊伍名稱'],
               j = '編碼',
               sep='-',
               suffix='.+')
df2 = df1[df1['編號'].notnull()]
df2 = df2.reset_index()
df2 = df2[['隊伍名稱','編號','暱稱']]
df2['編號'] = df2['編號'].astype(int)
df2.head()
隊伍名稱編號暱稱
0你說的都對隊5山楓葉紛飛
1你說的都對隊6
2你說的都對隊7安慕希
3你說的都對隊8信仰
4你說的都對隊20biubiu??
list1 = list(df['編號-0'].astype(int)) ## 此處一定要轉換為列表
df2['是否隊長'] = df2.apply(lambda x: 1 if x['編號'] in  list1 else 0 ,axis=1) #axis=1按行
df2.head()
隊伍名稱編號暱稱是否隊長
0你說的都對隊5山楓葉紛飛1
1你說的都對隊60
2你說的都對隊7安慕希0
3你說的都對隊8信仰0
4你說的都對隊20biubiu??0

3.將列名的順序與原表保持一致

(此處call一下我們組的小可愛們~)

cols = ['是否隊長','隊伍名稱','暱稱','編號']
df_data = df2.loc[:,cols]
df_data[df_data['隊伍名稱'] == '不急不躁我最棒✌️']
是否隊長隊伍名稱暱稱編號
821不急不躁我最棒✌️Lyndsey2
830不急不躁我最棒✌️Roman.90
840不急不躁我最棒✌️李鬆澤 Orwell91
850不急不躁我最棒✌️L.115
860不急不躁我最棒✌️阿塗163
870不急不躁我最棒✌️YHY68
880不急不躁我最棒✌️佬仔62
890不急不躁我最棒✌️JWJ30
900不急不躁我最棒✌️?154

任務3:美國大選投票情況

兩張資料表中分別給出了美國各縣(county)的人口數以及大選的投票情況,請解決以下問題:

county = pd.read_csv('練習題資料/county_population.csv')
county.head(2)
US CountyPopulation
0.Autauga County, Alabama55869
1.Baldwin County, Alabama223234
vote = pd.read_csv('練習題資料/president_county_candidate.csv')
vote.head(2)
statecountycandidatepartytotal_voteswon
0DelawareKent CountyJoe BidenDEM44552True
1DelawareKent CountyDonald TrumpREP41009False

問題1:有多少縣滿足總投票數超過縣人口數的一半

1.觀察資料,發現county的US County包含了vote中的county和state欄位,因此要先對資料進行處理,得到一個主鍵,之後再將滿足條件的值選擇出來

vote['US County'] = vote.apply(lambda x :'.'+x['county']+', '+x['state'],axis=1)
vote.head(2)
statecountycandidatepartytotal_voteswontUS County
0DelawareKent CountyJoe BidenDEM44552TrueNaN.Kent County, Delaware
1DelawareKent CountyDonald TrumpREP41009FalseNaN.Kent County, Delaware
vote_sum = vote.groupby(['US County'])['total_votes'].sum()
vote_sum = vote_sum.to_frame()
vote_sum.reset_index()
vote_sum.head()
total_votes
US County
.Abbeville County, South Carolina12433
.Abbot, Maine417
.Abington, Massachusetts9660
.Acadia Parish, Louisiana28425
.Accomack County, Virginia16962
county_vote_sum = county.merge(vote_sum, on=['US County'], how='left')
county_1 = county_vote_sum[county_vote_sum['total_votes']/county_vote_sum['Population']>0.5]
county_1['US County'].head()
11    .Choctaw County, Alabama
12     .Clarke County, Alabama
13       .Clay County, Alabama
16    .Colbert County, Alabama
17    .Conecuh County, Alabama
Name: US County, dtype: object

問題2:把州(state)作為行索引,把投票候選人作為列名,列名的順序按照候選人在全美的總票數由高到低排序,行列對應的元素為該候選人在該州獲得的總票數

1.根據問題的理解,也就是要將候選人轉換為列

vote2 = vote[['state','candidate','total_votes']]
vote2.head(2)
statecandidatetotal_votes
0DelawareJoe Biden44552
1DelawareDonald Trump41009
pivot_vote = vote2.pivot_table(index = 'state',
                        columns = 'candidate',
                        values = 'total_votes',
                        aggfunc='sum')
pivot_vote.head()
candidateNone of these candidatesWrite-insAlyson KennedyBill HammonsBlake HuberBrian CarrollBrock PierceBrooke PaigeChristopher LaFontaineConnie Gammon...Mark CharlesPhil CollinsPresident BoddiePrincess Jacob-FambroRichard DuncanRicki Sue KingRocky De La FuenteSheila Samm TittleTom HoeflingZachary Scalf
state
AlabamaNaN7312.0NaNNaNNaNNaNNaNNaNNaNNaN...NaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
AlaskaNaN34210.0NaNNaNNaNNaN825.0NaNNaNNaN...NaNNaNNaNNaNNaNNaN318.0NaNNaNNaN
ArizonaNaN2032.0NaNNaNNaNNaNNaNNaNNaNNaN...NaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
ArkansasNaNNaNNaNNaNNaN1713.02141.0NaNNaN1475.0...NaN2812.0NaNNaNNaNNaN1321.0NaNNaNNaN
CaliforniaNaN80.0NaNNaNNaNNaNNaNNaNNaNNaN...NaNNaNNaNNaNNaNNaN60155.0NaNNaNNaN

5 rows × 38 columns

2.將列的順序按照總票數進行調整,這裡先找到候選人和總票數,之後再進行排序,最後再進行列調整。

注意:做了reset_index()之後一定要賦值到原來的表,否則原表再次使用的時候依然不會變

rank = vote2.groupby('candidate')['total_votes'].sum()
rank = rank.to_frame()
rank2 = rank.sort_values('total_votes', ascending = False)
rank2 = rank2.reset_index()
new_rank = list(rank2['candidate'])
state_vote = pivot_vote.loc[:,new_rank]
state_vote.head()
candidateJoe BidenDonald TrumpJo JorgensenHowie HawkinsWrite-insRocky De La FuenteGloria La RivaKanye WestDon BlankenshipBrock Pierce...Tom HoeflingRicki Sue KingPrincess Jacob-FambroBlake HuberRichard DuncanJoseph KishoreJordan ScottGary SwingKeith McCormicZachary Scalf
state
Alabama849648.01441168.025176.0NaN7312.0NaNNaNNaNNaNNaN...NaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
Alaska153405.0189892.08896.0NaN34210.0318.0NaNNaN1127.0825.0...NaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
Arizona1672143.01661686.051465.0NaN2032.0NaNNaNNaNNaNNaN...NaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
Arkansas423932.0760647.013133.02980.0NaN1321.01336.04099.02108.02141.0...NaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
California11109764.06005961.0187885.081025.080.060155.051036.0NaNNaNNaN...NaNNaNNaNNaNNaNNaNNaNNaNNaNNaN

5 rows × 38 columns

問題3:每一個州下設若干縣,定義拜登在該縣的得票率減去川普在該縣的得票率為該縣的BT指標,若某個州所有縣BT指標的中位數大於0,則稱該州為Biden State,請找出所有的Biden State

1.首先我們將資料篩選出僅有拜登和川普的資料,此處使用isin,接著將拜登和川普放置到列,方便我們之後拼接總的的票數和BT指標的中位數

df_vote = vote[vote['candidate'].isin(['Joe Biden','Donald Trump'])]
df_vote1 = df_vote[['state','county','candidate','total_votes']]
df_vote2 = df_vote1.pivot_table(index = ['state','county'],
                        columns = 'candidate',
                        values = 'total_votes',
                        aggfunc='sum')
df_vote2.head()
candidateDonald TrumpJoe Biden
statecounty
AlabamaAutauga County198387503
Baldwin County8354424578
Barbour County56224816
Bibb County75251986
Blount County247112640

2.開始計算得票率,首先找到縣的總投票數,然後將他拼入上面的表中,計算出得票率,再計算出該縣的BT指標

county_vote = vote.groupby(['state','county'])['total_votes'].sum()
county_rate = df_vote2.merge(county_vote, on=['state','county'] ,how='left')
county_rate['Donald Trump'] =county_rate['Donald Trump']/county_rate['total_votes']
county_rate['Joe Biden'] =county_rate['Joe Biden']/county_rate['total_votes']
county_rate['BT'] = county_rate['Joe Biden'] - county_rate['Donald Trump']
county_rate.head()
Donald TrumpJoe Bidentotal_votesBT
statecounty
AlabamaAutauga County0.7143680.27018427770-0.444184
Baldwin County0.7617140.224090109679-0.537623
Barbour County0.5345120.45788210518-0.076631
Bibb County0.7842630.2069839595-0.577280
Blount County0.8957160.09569427588-0.800022

3.計算該縣的BT指標的中位數

rate_date = county_rate.groupby('state')['BT'].median()
rate_date = rate_date.reset_index()
BidenState = rate_date[rate_date['BT']>0]
BidenState
stateBT
4California0.084957
6Connecticut0.082626
7Delaware0.040712
8District of Columbia0.895536
11Hawaii0.321145
21Massachusetts0.251015
30New Jersey0.066718
39Rhode Island0.136207
45Vermont0.242156

相關文章