【JP】Task Special & Task 11 综合练习(2020.12)

提问前先阅读此贴学习规范,同时要求问题表述清晰,报错相关的问题需以文字而非图片的形式给出代码与重要的错误信息。

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

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

\rm I=-\sum_{i}p(x_i)\log(p(x_i))

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

【数据下载】链接:https://pan.baidu.com/s/1leZZctxMUSW55kZY5WwgIw 密码:u6fd

>>>df1 = pd.read_csv('company.csv')
>>>df2 = pd.read_csv('company_data.csv')
>>>df1.head()
	证券代码	日期
0	#000007	2014
1	#000403	2015
2	#000408	2016
3	#000408	2017
4	#000426	2015
>>>df2.head()
    证券代码	日期	    收入类型	 收入额
0	1	    2008/12/31	1	     1.084218e+10
1	1	    2008/12/31	2	     1.259789e+10
2	1	    2008/12/31	3	     1.451312e+10
3	1	    2008/12/31	4	     1.063843e+09
4	1	    2008/12/31	5	     8.513880e+08

【参考答案】

df2['证券代码'] = df2['证券代码'].apply(lambda x:'#%06d'%x)
df2 = df2[df2['证券代码'].isin(df1['证券代码'])]
df2['日期'] = df2['日期'].apply(lambda x: int(x[:4]))
res = df2.groupby(['证券代码', '日期'])['收入额'].apply(lambda x: -((x/x.sum()*np.log(x/x.sum()))).sum()).reset_index()
res = df1.merge(res, how='left', on=['证券代码', '日期']).rename(columns={'收入额': '收入熵'})

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

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

	是否队长	队伍名称	    昵称    	编号
0	1	    你说的都对队	山枫叶纷飞	5
1	0	    你说的都对队	蔡	        6
2	0	    你说的都对队	安慕希	    7
3	0	    你说的都对队	信仰	    8
4	0	    你说的都对队	biubiu🙈🙈	20
...	...	    ...	        ...	        ...
141	0	    七星联盟	    Daisy	    63
142	0	    七星联盟    	One Better	131
143	0	    七星联盟    	rain	    112
144	1	    应如是	    思无邪	    54
145	0	    应如是	    Justzer0	58

【数据下载】链接:https://pan.baidu.com/s/1ses24cTwUCbMx3rvYXaz-Q 密码:iz57

【参考答案】

df = pd.read_excel('组队信息汇总表(Pandas).xlsx')
temp = df.iloc[:,1::2].set_index('队伍名称').T.reset_index(drop=True)
temp['是否队长'] = np.r_[[1], np.zeros(temp.shape[0]-1)].astype('int')
melted = temp.melt(id_vars = '是否队长', value_vars = temp.columns[:-1], var_name = '队伍名称', value_name = '昵称').dropna().reset_index(drop=True)
number = pd.concat([df.iloc[:, 2*(i+1): 2*(i+2)].T.reset_index(drop=True).T for i in range(11)]).rename({0:'编号', 1:'昵称'}, axis=1).dropna().reset_index(drop=True)
res = melted.merge(number, how='left', on='昵称')

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

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

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

【数据下载】链接:https://pan.baidu.com/s/182rr3CpstVux2CFdFd_Pcg 提取码:q674

【参考答案】

第一问:

df = pd.read_csv('president_county_candidate.csv')
df_pop = pd.read_csv('county_population.csv')
temp = df_pop['US County'].copy()
df_pop['state'] = temp.apply(lambda x:x.split(', ')[1])
df_pop['county'] = temp.apply(lambda x:x.split(', ')[0][1:])
df_pop = df_pop.drop(['US County'],axis=1)
df = df.merge(df_pop, on=['state','county'],how='left')
df['pop_rate'] = df['total_votes']/df['Population']
res = df.groupby(['state','county'])['pop_rate'].agg(lambda x:x.sum())
(res>0.5).sum()

第二问:

res = df.pivot_table(index='state',columns='candidate',values='total_votes',aggfunc='sum').reindex(df.groupby('candidate')['total_votes'].sum().sort_values(ascending=False).index,axis=1)

第三问:

def select(x):
    def inner_select(inner_x):
        Total = inner_x.total_votes.sum()
        Biden = inner_x.query('candidate=="Joe Biden"').total_votes.sum()
        Trump = inner_x.query('candidate=="Donald Trump"').total_votes.sum()
        return (Biden-Trump)/Total
    res = x.groupby('county')[['candidate','total_votes']].apply(inner_select)
    return res.median() > 0
df.groupby('state').filter(select).state.unique()


请问这里的公司信息如何对应?

#000007对应下面的7,df2的前面补0至6位加#

【任务四】显卡日志

下面给出了3090显卡的性能测评日志结果,每一条日志有如下结构:

Benchmarking #2# #4# precision type #1#
#1#  model average #2# time :  #3# ms

其中#1#代表的是模型名称,#2#的值为train(ing)inference,表示训练状态或推断状态,#3#表示耗时,#4#表示精度,其中包含了float, half, double三种类型,下面是一个具体的例子:

Benchmarking Inference float precision type resnet50
resnet50  model average inference time :  13.426570892333984 ms

请把日志结果进行整理,变换成如下状态,model_i用相应模型名称填充,按照字母顺序排序,数值保留三位小数:

Training_half Training_float Training_double Inference_half Inference_float Inference_double
model_1 0.954 0.901 0.357 0.281 0.978 1.130
model_2 0.360 0.794 0.011 1.083 1.137 0.394

【数据下载】链接:https://pan.baidu.com/s/1CjfdtavEywHtZeWSmCGv3A 提取码:4mui

【参考答案】

df = pd.read_table('benchmark.txt').iloc[9:-2].reset_index(drop=True)
res1 = df.loc[0::2,'start'].str.extract('Benchmarking (?P<One>Training|Inference) (?P<Two>float|half|double) precision type (?P<Three>\w+)').reset_index(drop=True)
res2 = pd.to_numeric(df.loc[1::2,'start'].str.extract('.+time :  (?P<Time>\d+\.\d{3}).+').Time).reset_index(drop=True)
res = pd.concat([res1.One +'_'+ res1.Two, res1.Three, res2],1).set_index([0,'Three']).unstack('Three').droplevel(0, axis=1).T
res = res.reindex(pd.MultiIndex.from_product([['Training','Inference'],['half','float','double']]).map(lambda x:x[0]+'_'+x[1]),axis=1)

【任务五】水压站点的特征工程

df1df2中分别给出了18年和19年各个站点的数据,其中列中的H0H23分别代表当天0点至23点;df3中记录了18-19年的每日该地区的天气情况,请完成如下的任务:

import pandas as pd
import numpy as np
df1 = pd.read_csv('yali18.csv')
df2 = pd.read_csv('yali19.csv')
df3 = pd.read_csv('qx1819.csv')
  • 通过df1df2构造df,把时间设为索引,第一列为站点编号,第二列为对应时刻的压力大小,排列方式如下(压力数值请用正确的值替换):
                       站点    压力
2018-01-01 00:00:00       1    1.0
2018-01-01 00:00:00       2    1.0
...                     ...    ...
2018-01-01 00:00:00      30    1.0
2018-01-01 01:00:00       1    1.0
2018-01-01 01:00:00       2    1.0
...                     ...    ...
2019-12-31 23:00:00      30    1.0
  • 在上一问构造的df基础上,构造下面的特征序列或DataFrame,并把它们逐个拼接到df的右侧

    • 当天最高温、最低温和它们的温差
    • 当天是否有沙暴、是否有雾、是否有雨、是否有雪、是否为晴天
    • 选择一种合适的方法度量雨量/下雪量的大小(构造两个序列分别表示二者大小)
    • 限制只用4列,对风向进行0-1编码(只考虑风向,不考虑大小)
  • df的水压一列构造如下时序特征:

    • 当前时刻该站点水压与本月的相同整点时间该站点水压均值的差,例如当前时刻为2018-05-20 17:00:00,那么对应需要减去的值为当前月所有17:00:00时间点水压值的均值
    • 当前时刻所在周的周末该站点水压均值与工作日水压均值之差
    • 当前时刻向前7日内,该站点水压的均值、标准差、0.95分位数、下雨天数与下雪天数的总和
    • 当前时刻向前7日内,该站点同一整点时间水压的均值、标准差、0.95分位数
    • 当前时刻所在日的该站点水压最高值与最低值出现时刻的时间差

【数据下载】链接:https://pan.baidu.com/s/1Tqad4b7zN1HBbc-4t4xc6w 提取码:ijbd

这里提供一种思路,对于度量雨量的,群里看小伙伴是手动罗列的几种,麻烦且会漏,使用categories可以获取全部类别,再根据正则可以找出所有雨量的类型数量。之后可以使用zip创建字典表,然后对应的就可以完成任务了。