pandas-task-special.md

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

【题目描述】一个企业的产业收入多样性可以仿照信息熵的概念来定义收入熵指标:

在这里插入图片描述

其中 p(xi)是企业该年某产业收入额占该年所有产业总收入的比重。在company.csv中存有需要计算的企业和年份,在company_data.csv中存有企业、各类收入额和收入年份的信息。现请利用后一张表中的数据,在前一张表中增加一列表示该公司该年份的收入熵指标 I。

df1 = pd.read_csv('./data/task_special/company.csv')
df2 = pd.read_csv('./data/task_special/company_data.csv')
df1.head(3)

表一

证券代码日期
0#0000072014
1#0004032015
2#0004082016

表二

证券代码日期收入类型收入额
012008/12/3111.08422e+10
112008/12/3121.25979e+10
212008/12/3131.45131e+10

下面是我的解题过程。
第一步是按照证券代码对两表进行连接操作,不过两个表的证券代码格式不一致,表一的是object个数,形式为”#00数字“的格式,表二是int型数字。我们需要统一。

连接方法1

方法一:将 df1的证券代码转为数字,再进行连接。
将复杂的形式简化比较简单,不过看了下题目是需要将指标增加在表一,因此尽可能不要改动表一比较好,于是我将表二改动以适应表一。

df1['证券代码']=[int(str(i).split('#')[-1]) for i in df1['证券代码']]
df1.merge(df2,on='证券代码',how='left').head(3)

连接结果

证券代码日期_x日期_y收入类型收入额
0720142008/12/3118.63e+06
1720142008/12/3124.25842e+06
2720142008/12/3131.06108e+08

连接方法2

#连接方法2 df2的证券代码加上#和0 
code_len=6
df2['证券代码']=['#'+(code_len-len(str(i)))*str(0)+ 
				str(i) for i in df2['证券代码']]
df1.merge(df2,on='证券代码',how='left').head(3)

连接后

证券代码日期_x日期_y收入类型收入额
0#00000720142008/12/3118.63e+06
1#00000720142008/12/3124.25842e+06
2#00000720142008/12/3131.06108e+08

连接后我又陷入了迷茫,这咋俩日期还不一致呢?不要慌,让我们打印一下具体情况,表二证券代码是从7号的,我们就打印下表二7号证券代码的数据。

df2.loc[df2['证券代码']==7]

在这里插入图片描述
好家伙,有356行数据,而且日期是从2008到2016这么多。我们再看看一共有多少种日期。

df2.loc[df2['证券代码']==7]['日期'].unique()

>>>输出为
array(['2008/12/31', '2009/12/31', '2010/12/31', '2011/12/31',
       '2012/12/31', '2013/12/31', '2014/12/31', '2015/12/31',
       '2016/12/31'], dtype=object)

一共九种日期,日期是从08-16年每年最后一天。好了这下大概理解题意了。
结果还是理解错了题意。。。不过做到最后一步才发现,将错就错了。重要的是知识点的掌握,后续再完善。

  1. 我们要找表一证券代码对应表二证券代码的所有数据
  2. 同一证券代码再去找表一对应年限的收入额,汇总收入额
  3. 2的结果和该证券代码对应所有年限的收入额进行一些计算。

现在我们完成了1,继续完成2,3。
任务2.同一证券代码再去找表一对应年限的收入额,汇总收入额。
首先我们将刚刚通过证券代码连接的表记为df3,再将日期_y也就是原表二的日期只保留年份,方便和表一的日期对比。

df3['日期_y']=[i.split('/')[0] for i in df3['日期_y']]

更新完日期后的表3前五行

证券代码日期_x日期_y收入类型收入额
0#0000072014200818.63e+06
1#0000072014200824.25842e+06
2#0000072014200831.06108e+08
3#0000072014200841.54509e+07
4#0000072014200852.08143e+07

接着我们分别计算同一证券代码和该证券代码下指定日期的收入总和以及同一证券代码所有日期的的收入总和。自然而想到分组求和。

同一证券代码和该证券代码下指定日期的收入总和

res1=df3.groupby(['证券代码','日期_x'])['收入额'].agg([('single_sum','sum')]).reset_index()
res1.head(5)
证券代码日期_xsingle_sum
0#00000720142.05236e+10
1#00040320156.24456e+10
2#00040820166.51739e+10
3#00040820176.51739e+10
4#00042620158.72652e+10

同一证券代码所有日期的的收入总和

证券代码all_sum
0#0000072.05236e+10
1#0004036.24456e+10
2#0004081.30348e+11
3#0004262.61796e+11
4#0005111.95463e+11

最后就只剩3. 将2的结果和该证券代码对应所有年限的收入额进行一些计算。

res=res1.merge(res2,on=['证券代码'],how='left')
res.head(5)
证券代码日期_xsingle_sumall_sum
0#00000720142.05236e+102.05236e+10
1#00040320156.24456e+106.24456e+10
2#00040820166.51739e+101.30348e+11
3#00040820176.51739e+101.30348e+11
4#00042620158.72652e+102.61796e+11

计算每行的熵

res['entropy']=[ -(i/j)*math.log2((i/j)) for i,j in 
			zip(res.single_sum,res.all_sum)]
df1['entropy']=res['entropy']
df1.head(5)
证券代码日期entropy
0#0000072014-0
1#0004032015-0
2#00040820160.5
3#00040820170.5
4#00042620150.528321

【任务二】组队学习信息表的变换

【题目描述】请把组队学习的队伍信息表变换为如下形态,其中“是否队长”一列取1表示队长,否则为0

在这里插入图片描述

首先看下原表格样式

df=pd.read_excel('./data/task_special/组队信息汇总表(Pandas).xlsx')
df.head(3)

在这里插入图片描述

解决方案

这个题拿到手想了很久宽表转换成长表,但是怎么想都不对,因为题目要求的转换后数据数量就不一样,而长宽表的相互转换是只改变形式不改变数量和数值的。
对第一行数据去除空值后看下

df.loc[0].dropna().to_markdown()
0
所在群Pandas数据分析
队伍名称你说的都对队
队长编号5
队长_群昵称山枫叶纷飞
队员1 编号6
队员_群昵称
队员2 编号7.0
队员_群昵称.1安慕希
队员3 编号8.0
队员_群昵称.2信仰
队员4 编号20.0
队员_群昵称.3biubiu🙈🙈

回顾之前的作业想到有类似的操作。
每个队伍的人数都不同,因此将每个队伍的信息抽取出来整理,然后加入列表,最后将这些信息合并。下面是我的主要代码:

L=[]
team_num=len(df)
cols=['是否队长','队伍名称','昵称','编号']
for i in range(team_num):
    df1=df.loc[i].dropna()
    team_mem=int((len(df1)-2)/2)
    for i in range(team_mem):
        #是否队长
        if i == 0:
            L.append(pd.DataFrame([1,df1[1],df1[3+2*i],
            					df1[3+2*i-1]]).T)
        else:
            L.append(pd.DataFrame([0,df1[1],df1[3+2*i],
            					df1[3+2*i-1]]).T)
res = pd.concat(L)
res.index=[i for i in range(len(res))]
res.columns=cols
res.tail(5)

看下最后几列,现在已经满足条件了。

是否队长队伍名称昵称编号
1410七星联盟Daisy63
1420七星联盟One Better131
1430七星联盟rain112
1441应如是思无邪54
1450应如是Justzer058

打印下自己小队的嘿嘿。

是否队长队伍名称昵称编号
1251Attention!keep干饭阿芒Aris21
1260Attention!keep干饭Alex152
1270Attention!keep干饭Jie95
1280Attention!keep干饭梦想家104

【任务三】美国大选投票情况

【题目描述】两张数据表中分别给出了美国各县(county)的人口数以及大选的投票情况,请解决以下问题:

  • 有多少县满足总投票数超过县人口数的一半
  • 把州(state)作为行索引,把投票候选人作为列名,列名的顺序按照候选人在全美的总票数由高到低排序,行列对应的元素为该候选人在该州获得的总票数
# 此处是一个样例,实际的州或人名用原表的英语代替
            拜登   川普
威斯康星州   2      1
德克萨斯州   3      4
  • 每一个州下设若干县,定义拜登在该县的得票率减去川普在该县的得票率为该县的BT指标,若某个州所有县BT指标的中位数大于0,则称该州为Biden State,请找出所有的Biden State

时间不够充裕,第三题待思考。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值