DataWhale-Pandas数据分析-Task7

文章目录

DataWhale-Pandas数据分析-Task7

记录DataWhale的Pandas数据分析的学习过程,本次是期中测试,测试前面6章学的怎么样(划水的菜鸡瑟瑟发抖)。本篇文章中的测试题及源数据可以从此链接中下载,需要的可以点击链接自取。

【任务一】企业收入的多样性

DataWhale-Pandas数据分析-Task7
DataWhale-Pandas数据分析-Task7
思路:有两个表company和company_data,最后的结果应该是两个表连接成一个表,需要在company_data这个表中统计出熵,基本方法是先根据证券代码和日期分组求和,然后使用变换transform()方法将 p ( x i ) ∗ l o g ( p ( x i ) ) p(x_i)*log(p(x_i)) p(xi​)∗log(p(xi​))入到company_data表中,然后再根据先根据证券代码和日期分组求和,即可求出熵。

import pandas as pd
import numpy as np

df1 = pd.read_csv('company.csv')
df2 = pd.read_csv('company_data.csv')

df2=df2.loc[df2['收入额']>0,:]#df2中有负值,无法计算熵,所以先把负值所在的列删掉。
gb=df2.groupby(['证券代码','日期'])['收入额']#根据证券代码和日期分组
s1=df2['收入额']/gb.transform('sum')#使用变换transform()方法,求每一行收入与当年总收入的比例。
df2['temp']=-s1*np.log(s1)
df3=df2.groupby(['证券代码','日期'])['temp'].agg([('熵','sum')]).reset_index()#使用聚合函数求熵,生成新的表df3

df3['日期']=df3['日期'].apply(lambda x:int(x.split('/')[0]))#将表df3的日期一列改为和df1类型一样的方式,方便后面与df1连接
df1['证券代码']=df1['证券代码'].apply(lambda x:int(x[1:]))#将表df1的证券代码一列改为和df3类型一样,方便与df3连接。
df1=df1.merge(df3,on=['证券代码','日期'])#df1与df3连接,将熵加入到df1中.
df1.head()
>>>
>   证券代码    日期         熵
0     7  2014  3.070462
1   403  2015  2.790585
2   408  2016  2.818541
3   426  2015  3.084266
4   426  2016  2.988900

#看一下熵的分布特征
df1['熵'].describe()
>>>
>count    955.000000
mean       3.338334
std        0.410689
min        1.837489
25%        3.010368
50%        3.334039
75%        3.724752
max        4.068474
Name: 熵, dtype: float64

【任务二】

DataWhale-Pandas数据分析-Task7
思路:我们先看一下原来表长什么样子:
DataWhale-Pandas数据分析-Task7
很明显,原表是一个宽表,目标表格是一个长表,可以考虑先用使用melt()函数将宽表变为长表,先将队员昵称从列压缩到行,得到了包含昵称到编号映射关系的新的列:“昵称-编号”,然后利用这个映射关系,为每一个昵称找到其对应的编号,具体代码如下:

df=pd.read_excel('组队信息汇总表(Pandas).xlsx')

#导入excel表格以后,列索引的值有些混乱,为了后续方便找到昵称和编号的对应关系,先重新设置一下索引的值。
df=df.rename(columns={'队员_群昵称':'队员_群昵称.1','队员_群昵称.1':'队员_群昵称.2','队员_群昵称.2':'队员_群昵称.3','队员_群昵称.3':'队员_群昵称.4',\
                        '队员_群昵称.4':'队员_群昵称.5','队员_群昵称.5':'队员_群昵称.6','队员_群昵称.6':'队员_群昵称.7','队员_群昵称.7':'队员_群昵称.8',\
                        '队员_群昵称.8':'队员_群昵称.9','队员_群昵称.9':'队员_群昵称.10','队员10编号':'队员10 编号'})

#使用melt将队员昵称从列压缩到行
df1=df.melt(value_vars=['队长_群昵称','队员_群昵称.1','队员_群昵称.2','队员_群昵称.3','队员_群昵称.4','队员_群昵称.5',\
                        '队员_群昵称.6','队员_群昵称.7','队员_群昵称.8','队员_群昵称.9','队员_群昵称.10'],#压缩的列。
        var_name='昵称-编号',#将压缩后形成的新列命名为昵称-编号
        value_name='昵称',
        id_vars=['所在群','队伍名称','队长编号','队员1 编号','队员2 编号','队员3 编号','队员4 编号','队员5 编号',\
                 '队员6 编号','队员7 编号','队员8 编号','队员9 编号','队员10 编号'])

df1=df1.loc[df1['昵称'].notnull(),:]#因为有的队队员人数不足10个,所以这里需要去除昵称为空的行。

#根据‘昵称-编号’这一列找到‘昵称’对应的编号。
def func(x):
        if x['昵称-编号']=='队长_群昵称':
                return int(x['队长编号'])

        else:
                return int(x['队员'+x['昵称-编号'].split('.')[1]+' 编号'])

df1['编号']=df1.apply(func,axis=1)
df1['是否队长']=df1['昵称-编号'].apply(lambda x: 1 if x=='队长_群昵称' else 0)

df_final=df1[['是否队长','队伍名称','昵称','编号']].sort_values(['队伍名称','是否队长'],ascending=[True,False]).reset_index(drop=True)

结果:
DataWhale-Pandas数据分析-Task7

【任务三】

DataWhale-Pandas数据分析-Task7
1.思路:先分组后统计每个县投票总人数,再与人口表连接,求出投票总人数超过总数一半的县.

df1 = pd.read_csv('county_population.csv')
df2 = pd.read_csv('president_county_candidate.csv')

df_temp=df2.groupby(['state','county'])['total_votes'].agg({'sum'})#先分组,再求和
df_temp.index=df_temp.index.map(lambda x:'.'+x[1]+', '+x[0])#将两层列索引压缩成一层,方便后续与df1连接
df_temp=df_temp.reset_index().rename(columns={'index':'US County'})#将列名重命名为和df1一样。

df_m=df1.merge(df_temp,on='US County')#df_temp与df1连接
s_country=df_m.loc[df_m['sum']/df_m['Population']>0.5]['US County'].reset_index(drop=True)#根据条件索引
>>>
>0    .Choctaw County, Alabama
1     .Clarke County, Alabama
2       .Clay County, Alabama
3    .Colbert County, Alabama
4    .Conecuh County, Alabama
Name: US County, dtype: object

2 .思路:先根据洲名和候选人名分组统计每个候选人在一个州的总票数,然后使用pivot()函数对列表进行变形,最后生成一个每个候选在全国的总选票的Series加入到列表中,根据总选票的多少,使用sort_values(axis=1)对列进行排序。

df_temp=df2.groupby(['state','candidate'])['total_votes'].sum().reset_index()#分组
df_temp=df_temp.pivot(index='state',columns='candidate',values='total_votes')#使用pivot()变形
s=pd.Series(df_temp.apply(lambda x:x.sum()),name='all')#生成一个新的Series,计算每个候选在全国的总选票。
df_temp=df_temp.append(s)#将s加入到表格df_temp中
df_temp.sort_values(by='all',ascending=False,axis=1)#使用sort_values(axis=1)对列进行排序

结果的表格太宽,截图显示一下:
DataWhale-Pandas数据分析-Task7
3.

上一篇:使用pandas.concat()将两张excel表合并


下一篇:WebApi Mvc Controller httpclient 数据交互