【12月DW打卡】joyful-pandas - pandas 中期练习(企业收入的信息熵多样性、组队学习信息表的变换、美国大选投票情况)

pandas 中期练习

小结

  • 原文链接: http://datawhale.club/t/topic/579/2
  • 转换命令:jupyter nbconvert --to markdown E:\PycharmProjects\TianChiProject\00_山枫叶纷飞\competitions\008_joyful-pandas\pandas_mid_test.ipynb
import numpy as np
import pandas as pd
import os


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

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

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

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

file_prefix = '/00_山枫叶纷飞/competitions/008_joyful-pandas'

com_df = pd.read_csv(file_prefix + '/mid_test/Company.csv')
com_data_df = pd.read_csv(file_prefix + '/mid_test/Company_data.csv')
com_df.head(6)
com_data_df.head(6)
result_df = com_df.copy()
# 先清洗格式
result_df['证券代码'] = result_df['证券代码'].apply(lambda x:int(str(x).split('#')[1]))
com_data_df['日期'] = com_data_df['日期'].apply(lambda x: int(str(x).split('/')[0]))
# 进行join
idxs = ['证券代码', '日期']

join_df = result_df.set_index(idxs).join(com_data_df.set_index(idxs), on=idxs, how="left")
join_df = join_df.sort_index()
join_df
def group_income_type(x):
    return x/x.sum()

#求p(xi)是企业该年某产业收入额占该年所有产业总收入的比重。
join_df['p(xi)'] = join_df.groupby(idxs)['收入额'].transform(group_income_type)

join_df.head()
收入类型 收入额 p(xi)
证券代码 日期
7 2014 1.0 61461724.73 0.020618
2014 2.0 0.00 0.000000
2014 3.0 61461724.73 0.020618
2014 4.0 98631112.52 0.033087
2014 5.0 80000000.00 0.026837

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

# 计算多样性
def group_vari_type(x):
    x = abs(x)
    return np.sum(-1 * x * np.log(x))
join_df = join_df.groupby(idxs)['p(xi)'].agg(group_vari_type)

D:\DevInstallProjects\Miniconda3\lib\site-packages\pandas\core\series.py:726: RuntimeWarning: divide by zero encountered in log
  result = getattr(ufunc, method)(*inputs, **kwargs)





证券代码  日期  
7     2014    3.070462
403   2015    2.790585
408   2016    2.818541
      2017    0.000000
426   2015    3.084266
Name: p(xi), dtype: float64
# 打印最终结果
join_df
证券代码    日期  
7       2014    3.070462
403     2015    2.790585
408     2016    2.818541
        2017    0.000000
426     2015    3.084266
                  ...   
600978  2011    3.319059
        2014    2.788100
        2015    3.012628
        2016    3.021157
        2017    0.000000
Name: p(xi), Length: 1048, dtype: float64

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

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

	是否队长	队伍名称	    昵称    	编号
0	1	    你说的都对队	山枫叶纷飞	5
1	0	    你说的都对队	蔡	        6
file_prefix = 'E:/PycharmProjects/TianChiProject/00_山枫叶纷飞/competitions/008_joyful-pandas'
team_df = pd.read_excel(file_prefix + '/mid_test/组队信息汇总表(Pandas).xlsx')
team_df.head()
所在群 队伍名称 队长编号 队长_群昵称 队员1 编号 队员_群昵称 队员2 编号 队员_群昵称.1 队员3 编号 队员_群昵称.2 ... 队员6 编号 队员_群昵称.5 队员7 编号 队员_群昵称.6 队员8 编号 队员_群昵称.7 队员9 编号 队员_群昵称.8 队员10编号 队员_群昵称.9
0 Pandas数据分析 你说的都对队 5 山枫叶纷飞 6 7.0 安慕希 8.0 信仰 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
1 Pandas数据分析 熊猫人 175 鱼呲呲 44 Heaven 37.0 吕青 50.0 余柳成荫 ... 25.0 Never say never 55.0 K 120.0 Y. 28.0 X.Y.Q 151.0 swrong
2 Pandas数据分析 中国移不动 107 Y's 124 🥕 75.0 Vito 146.0 张小五 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
3 Pandas数据分析 panda 11 太下真君 35 柚子 108.0 My 42.0 星星点灯 ... 157.0 Zys 158.0 不器 102.0 嘉平佑染 NaN NaN NaN NaN
4 Pandas数据分析 一路向北 13 黄元帅 15 16.0 未期 18.0 太陽光下 ... 23.0 🚀 169.0 听风 189.0 Cappuccino NaN NaN NaN NaN

5 rows × 24 columns

team_df.columns
Index(['所在群', '队伍名称', '队长编号', '队长_群昵称', '队员1 编号', '队员_群昵称', '队员2 编号',
       '队员_群昵称.1', '队员3 编号', '队员_群昵称.2', '队员4 编号', '队员_群昵称.3', '队员5 编号',
       '队员_群昵称.4', '队员6 编号', '队员_群昵称.5', '队员7 编号', '队员_群昵称.6', '队员8 编号',
       '队员_群昵称.7', '队员9 编号', '队员_群昵称.8', '队员10编号', '队员_群昵称.9'],
      dtype='object')

解题思路: 【任务二】 宽表转换为长表
~~没思路,改为暴力处理!!

cols = list(team_df.columns)
def construct_piece_df(is_leader, team_name, nick_name, id):
    if pd.isna(id) or pd.isna(nick_name):
        return pd.DataFrame()
    a_df = pd.DataFrame({'是否是队长': [is_leader],
                         '队伍名称': [team_name],
                         '昵称': [nick_name],
                         '编号': [int(id)]},
                        index=[id]
                        )
    return a_df
dfs = []
# '队员10编号' -> '队员10 编号'
team_df.rename(columns={'队员10编号': '队员10 编号',
                        '队员_群昵称': '队员_群昵称.0'}, inplace=True)
cols2 = list(team_df.columns)
for ith in range(team_df.shape[0]):
    row = team_df.iloc[ith, :] # Series
    # 加队长
    dfs.append(construct_piece_df(1, row['队伍名称'],
                                  row['队长_群昵称'], row['队长编号']))
    # 加进队员
    for i in range(1, 11):
        dfs.append(construct_piece_df(0,
                                      row['队伍名称'],
                                      row['队员_群昵称.%d' % (i-1)],
                                      row['队员%d 编号' % i]
                                      ))
ans_team_df_transfer = pd.concat(dfs)
ans_team_df_transfer.reset_index(drop=True, inplace=True)
ans_team_df_transfer
是否是队长 队伍名称 昵称 编号
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

146 rows × 4 columns

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

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

# county_population
population_csv = pd.read_csv(file_prefix + '/mid_test/county_population.csv')
# president_county_candidate
candidate_csv = pd.read_csv(file_prefix + '/mid_test/president_county_candidate.csv')
population_csv.head()
US County Population
0 .Autauga County, Alabama 55869
1 .Baldwin County, Alabama 223234
2 .Barbour County, Alabama 24686
3 .Bibb County, Alabama 22394
4 .Blount County, Alabama 57826
candidate_csv.head()
state county candidate party total_votes won
0 Delaware Kent County Joe Biden DEM 44552 True
1 Delaware Kent County Donald Trump REP 41009 False
2 Delaware Kent County Jo Jorgensen LIB 1044 False
3 Delaware Kent County Howie Hawkins GRN 420 False
4 Delaware New Castle County Joe Biden DEM 195034 True

有多少县满足总投票数超过县人口数的一半

pop_df = population_csv.copy()
pop_df['county'] = population_csv['US County'].apply(lambda x: str(x)[1:].split(', ')[0])
pop_df['state'] = population_csv['US County'].apply(lambda x: str(x)[1:].split(', ')[1])
join_df = pop_df.merge(candidate_csv, on='county', how='left')
join_df.columns
Index(['US County', 'Population', 'county', 'state_x', 'state_y', 'candidate',
       'party', 'total_votes', 'won'],
      dtype='object')
county_cnt_df = join_df.groupby(['county', 'state_x', 'Population'])[['total_votes']].agg(sum)
county_cnt_df.reset_index(inplace=True)
county_cnt_df['vote_percent'] = county_cnt_df['Population']/county_cnt_df['total_votes']
print('有多少县满足总投票数超过县人口数的一半: ')
county_cnt_df[county_cnt_df['vote_percent'] > 0.5].shape[0]
有多少县满足总投票数超过县人口数的一半: 





2059

把州(state)作为行索引,把投票候选人作为列名,列名的顺序按照候选人在全美的总票数由高到低排序,行列对应的元素为该候选人在该州获得的总票数.

此处是一个样例,实际的州或人名用原表的英语代替

            拜登   川普
威斯康星州   2      1
德克萨斯州   3      4

每一个州下设若干县,定义拜登在该县的得票率减去川普在该县的得票率为该县的BT指标,若某个州所有县BT指标的中位数大于0,则称该州为Biden State,请找出所有的Biden State

candidate_csv.columns
Index(['state', 'county', 'candidate', 'party', 'total_votes', 'won'], dtype='object')
vote_pivot = candidate_csv.dropna(subset=['state','county','candidate']).pivot_table(index = ['state','county'],
                             columns = 'candidate',
                             values = 'total_votes',
                             aggfunc='sum',
                             margins=True)
#  'Joe Biden', 'Donald Trump'
vote_pivot.columns
Index([' None of these candidates', ' Write-ins', 'Alyson Kennedy',
       'Bill Hammons', 'Blake Huber', 'Brian Carroll', 'Brock Pierce',
       'Brooke Paige', 'Christopher LaFontaine', 'Connie Gammon',
       'Dario Hunter', 'Don Blankenship', 'Donald Trump', 'Gary Swing',
       'Gloria La Riva', 'Howie Hawkins', 'Jade Simmons', 'Jerome Segal',
       'Jesse Ventura', 'Jo Jorgensen', 'Joe Biden', 'Joe McHugh',
       'John Richard Myers', 'Jordan Scott', 'Joseph Kishore', 'Kanye West',
       'Keith McCormic', 'Kyle Kopitke', 'Mark Charles', 'Phil Collins',
       'President Boddie', 'Princess Jacob-Fambro', 'Richard Duncan',
       'Ricki Sue King', 'Rocky De La Fuente', 'Sheila Samm Tittle',
       'Tom Hoefling', 'Zachary Scalf', 'All'],
      dtype='object', name='candidate')
vs_df = vote_pivot[['Joe Biden', 'Donald Trump', 'All']]
vs_df['Biden_vote_diff'] = vs_df['Joe Biden']/vs_df['All'] - vs_df['Donald Trump']/vs_df['All']
<ipython-input-51-f92bc0969e97>:2: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  vs_df['Biden_vote_diff'] = vs_df['Joe Biden']/vs_df['All'] - vs_df['Donald Trump']/vs_df['All']
vs_df.columns
Index(['Joe Biden', 'Donald Trump', 'All', 'Biden_vote_diff'], dtype='object', name='candidate')

若某个州所有县BT指标的中位数大于0,则称该州为Biden State,请找出所有的Biden State

vs_df.reset_index(inplace=True)
ret_median_State_df = vs_df.groupby('state')[['Biden_vote_diff']].agg('median')
biden_State_df = ret_median_State_df[ret_median_State_df['Biden_vote_diff']>0]
biden_State_df.reset_index(inplace=True)
ans = list(biden_State_df['state'])
ans.remove('All')
print('biden_State_names:', ans)
biden_State_names: ['California', 'Connecticut', 'Delaware', 'District of Columbia', 'Hawaii', 'Massachusetts', 'New Jersey', 'Rhode Island', 'Vermont']
posted @ 2021-01-01 21:19  山枫叶纷飞  阅读(174)  评论(0编辑  收藏  举报