Day7-Python综合作业1(DataWhale)

这篇博客介绍了Python在数据处理中的应用,包括计算企业收入熵值,转换组队学习信息表,以及分析美国大选投票情况。在企业收入任务中,通过数据转换和分组计算熵值;在组队信息任务中,将多列信息整合为队长标识;在选举分析中,涉及投票数与人口比较,候选人得票率计算以及州的BT指标计算,寻找Biden State。
摘要由CSDN通过智能技术生成
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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值