2-2

 
lect02_eg02 Last Checkpoint: 11/06/2017 (autosaved)
 
 
 
 

数据合并及分组

 

1. 数据合并

 
 
 
 
 
 
import pandas as pd
staff_df = pd.DataFrame([{'姓名': '张三', '部门': '研发部'},
                        {'姓名': '李四', '部门': '财务部'},
                        {'姓名': '赵六', '部门': '市场部'}])
student_df = pd.DataFrame([{'姓名': '张三', '专业': '计算机'},
                        {'姓名': '李四', '专业': '会计'},
                        {'姓名': '王五', '专业': '市场营销'}])
print(staff_df)
print()
print(student_df)
 
 
 
   姓名   部门
0  张三  研发部
1  李四  财务部
2  赵六  市场部

     专业  姓名
0   计算机  张三
1    会计  李四
2  市场营销  王五
 
 
 
 
 
 
pd.merge(staff_df, student_df, how='outer', on='姓名')
# 或者
# staff_df.merge(student_df, how='outer', on='姓名')
 
 
 
 姓名部门专业
0 张三 研发部 计算机
1 李四 财务部 会计
2 赵六 市场部 NaN
3 王五 NaN 市场营销
 
 
 
 
 
 
pd.merge(staff_df, student_df, how='inner', on='姓名')
# 或者
# staff_df.merge(student_df, how='inner', on='姓名')
 
 
 
 姓名部门专业
0 张三 研发部 计算机
1 李四 财务部 会计
 
 
 
 
 
 
pd.merge(staff_df, student_df, how='left', on='姓名')
# 或者
# staff_df.merge(student_df, how='left', on='姓名')
 
 
 
 姓名部门专业
0 张三 研发部 计算机
1 李四 财务部 会计
2 赵六 市场部 NaN
 
 
 
 
 
 
pd.merge(staff_df, student_df, how='right', on='姓名')
# 或者
# staff_df.merge(student_df, how='right', on='姓名')
 
 
 
 姓名部门专业
0 张三 研发部 计算机
1 李四 财务部 会计
2 王五 NaN 市场营销
 
 
 
 
 
 
# 也可以按索引进行合并
staff_df.set_index('姓名', inplace=True)
student_df.set_index('姓名', inplace=True)
print(staff_df)
print(student_df)
 
 
 
     部门
姓名     
张三  研发部
李四  财务部
赵六  市场部
      专业
姓名      
张三   计算机
李四    会计
王五  市场营销
 
 
 
 
 
 
pd.merge(staff_df, student_df, how='left', left_index=True, right_index=True)
# 或者
# staff_df.merge(student_df, how='left', left_index=True, right_index=True)
 
 
 
 部门专业
姓名  
张三 研发部 计算机
李四 财务部 会计
赵六 市场部 NaN
 
 
 
 
 
 
# 当数据中的列名不同时,使用left_on,right_on
staff_df.reset_index(inplace=True)
student_df.reset_index(inplace=True)
print(staff_df)
print(student_df)
 
 
 
   姓名   部门
0  张三  研发部
1  李四  财务部
2  赵六  市场部
   姓名    专业
0  张三   计算机
1  李四    会计
2  王五  市场营销
 
 
 
 
 
 
staff_df.rename(columns={'姓名': '员工姓名'}, inplace=True)
student_df.rename(columns={'姓名': '学生姓名'}, inplace=True)
print(staff_df)
print(student_df)
 
 
 
  员工姓名   部门
0   张三  研发部
1   李四  财务部
2   赵六  市场部
  学生姓名    专业
0   张三   计算机
1   李四    会计
2   王五  市场营销
 
 
 
 
 
 
pd.merge(staff_df, student_df, how='left', left_on='员工姓名', right_on='学生姓名')
 
 
 
 员工姓名部门学生姓名专业
0 张三 研发部 张三 计算机
1 李四 财务部 李四 会计
2 赵六 市场部 NaN NaN
 
 
 
 
 
 
# 如果两个数据中包含有相同的列名(不是要合并的列)时,merge会自动加后缀作为区别
staff_df['地址'] = ['天津', '北京', '上海']
student_df['地址'] = ['天津', '上海', '广州']
print(staff_df)
print(student_df)
 
 
 
  员工姓名   部门  地址
0   张三  研发部  天津
1   李四  财务部  北京
2   赵六  市场部  上海
  学生姓名    专业  地址
0   张三   计算机  天津
1   李四    会计  上海
2   王五  市场营销  广州
 
 
 
 
 
 
pd.merge(staff_df, student_df, how='left', left_on='员工姓名', right_on='学生姓名')
 
 
 
 员工姓名部门地址_x学生姓名专业地址_y
0 张三 研发部 天津 张三 计算机 天津
1 李四 财务部 北京 李四 会计 上海
2 赵六 市场部 上海 NaN NaN NaN
 
 
 
 
 
 
# 也可指定后缀名称
pd.merge(staff_df, student_df, how='left', left_on='员工姓名', right_on='学生姓名', suffixes=('(公司)', '(家乡)'))
 
 
 
 员工姓名部门地址(公司)学生姓名专业地址(家乡)
0 张三 研发部 天津 张三 计算机 天津
1 李四 财务部 北京 李四 会计 上海
2 赵六 市场部 上海 NaN NaN NaN
 
 
 
 
 
 
# 也可以指定多列进行合并,找出同一个人的工作地址和家乡地址相同的记录
pd.merge(staff_df, student_df, how='inner', left_on=['员工姓名', '地址'], right_on=['学生姓名', '地址'])
 
 
 
 员工姓名部门地址学生姓名专业
0 张三 研发部 天津 张三 计算机
 
 
 
 
 
 
# apply使用
# 获取姓
staff_df['员工姓名'].apply(lambda x: x[0])
 
 
 
0    张
1    李
2    赵
Name: 员工姓名, dtype: object
 
 
 
 
 
 
# 获取名
staff_df['员工姓名'].apply(lambda x: x[1:])
 
 
 
0    三
1    四
2    六
Name: 员工姓名, dtype: object
 
 
 
 
 
 
# 结果合并
staff_df.loc[:, '姓'] = staff_df['员工姓名'].apply(lambda x: x[0])
staff_df.loc[:, '名'] = staff_df['员工姓名'].apply(lambda x: x[1:])
print(staff_df)
 
 
 
  员工姓名   部门  地址  姓  名
0   张三  研发部  天津  张  三
1   李四  财务部  北京  李  四
2   赵六  市场部  上海  赵  六
 

2. 数据分组

 
 
 
 
 
 
report_data = pd.read_csv('./2015.csv')
report_data.head()
 
 
 
 CountryRegionHappiness RankHappiness ScoreStandard ErrorEconomy (GDP per Capita)FamilyHealth (Life Expectancy)FreedomTrust (Government Corruption)GenerosityDystopia Residual
0 Switzerland Western Europe 1 7.587 0.03411 1.39651 1.34951 0.94143 0.66557 0.41978 0.29678 2.51738
1 Iceland Western Europe 2 7.561 0.04884 1.30232 1.40223 0.94784 0.62877 0.14145 0.43630 2.70201
2 Denmark Western Europe 3 7.527 0.03328 1.32548 1.36058 0.87464 0.64938 0.48357 0.34139 2.49204
3 Norway Western Europe 4 7.522 0.03880 1.45900 1.33095 0.88521 0.66973 0.36503 0.34699 2.46531
4 Canada North America 5 7.427 0.03553 1.32629 1.32261 0.90563 0.63297 0.32957 0.45811 2.45176
 
 
 
 
 
 
#groupby()
grouped = report_data.groupby('Region')
print(type(grouped))
 
 
 
<class 'pandas.core.groupby.DataFrameGroupBy'>
 
 
 
 
 
 
grouped['Happiness Score'].mean()
 
 
 
Region
Australia and New Zealand          7.285000
Central and Eastern Europe         5.332931
Eastern Asia                       5.626167
Latin America and Caribbean        6.144682
Middle East and Northern Africa    5.406900
North America                      7.273000
Southeastern Asia                  5.317444
Southern Asia                      4.580857
Sub-Saharan Africa                 4.202800
Western Europe                     6.689619
Name: Happiness Score, dtype: float64
 
 
 
 
 
 
grouped.size()
 
 
 
Region
Australia and New Zealand           2
Central and Eastern Europe         29
Eastern Asia                        6
Latin America and Caribbean        22
Middle East and Northern Africa    20
North America                       2
Southeastern Asia                   9
Southern Asia                       7
Sub-Saharan Africa                 40
Western Europe                     21
dtype: int64
 
 
 
 
 
 
# 迭代groupby对象
for group, frame in grouped:
    mean_score = frame['Happiness Score'].mean()
    max_score = frame['Happiness Score'].max()
    min_score = frame['Happiness Score'].min()
    print('{}地区的平均幸福指数:{},最高幸福指数:{},最低幸福指数{}'.format(group, mean_score, max_score, min_score))
 
 
 
Australia and New Zealand地区的平均幸福指数:7.285,最高幸福指数:7.2860000000000005,最低幸福指数7.284
Central and Eastern Europe地区的平均幸福指数:5.332931034482758,最高幸福指数:6.505,最低幸福指数4.218
Eastern Asia地区的平均幸福指数:5.626166666666666,最高幸福指数:6.297999999999999,最低幸福指数4.874
Latin America and Caribbean地区的平均幸福指数:6.144681818181818,最高幸福指数:7.226,最低幸福指数4.518
Middle East and Northern Africa地区的平均幸福指数:5.406899999999999,最高幸福指数:7.278,最低幸福指数3.0060000000000002
North America地区的平均幸福指数:7.273,最高幸福指数:7.4270000000000005,最低幸福指数7.119
Southeastern Asia地区的平均幸福指数:5.317444444444445,最高幸福指数:6.797999999999999,最低幸福指数3.819
Southern Asia地区的平均幸福指数:4.580857142857143,最高幸福指数:5.252999999999999,最低幸福指数3.575
Sub-Saharan Africa地区的平均幸福指数:4.202800000000001,最高幸福指数:5.477,最低幸福指数2.839
Western Europe地区的平均幸福指数:6.689619047619048,最高幸福指数:7.587000000000001,最低幸福指数4.857
 
 
 
 
 
 
# 自定义函数进行分组
# 按照幸福指数排名进行划分,1-10, 10-20, >20
# 如果自定义函数,操作针对的是index
report_data2 = report_data.set_index('Happiness Rank')
def get_rank_group(rank):
    rank_group = ''
    if rank <= 10:
        rank_group = '0 -- 10'
    elif rank <= 20:
        rank_group = '10 -- 20'
    else:
        rank_group = '> 20'
    return rank_group
grouped = report_data2.groupby(get_rank_group)
for group, frame in grouped:
    print('{}分组的数据个数:{}'.format(group, len(frame)))
 
 
 
0 -- 10分组的数据个数:10
10 -- 20分组的数据个数:10
> 20分组的数据个数:138
 
 
 
 
 
 
# 实际项目中,通常可以先人为构造出一个分组列,然后再进行groupby
# 按照score的整数部分进行分组
# 按照幸福指数排名进行划分,1-10, 10-20, >20
# 如果自定义函数,操作针对的是index
report_data['score group'] = report_data['Happiness Score'].apply(lambda score: int(score))
grouped = report_data.groupby('score group')
for group, frame in grouped:
    print('幸福指数整数部分为{}的分组数据个数:{}'.format(group, len(frame)))
 
 
 
幸福指数整数部分为2的分组数据个数:2
幸福指数整数部分为3的分组数据个数:19
幸福指数整数部分为4的分组数据个数:44
幸福指数整数部分为5的分组数据个数:49
幸福指数整数部分为6的分组数据个数:29
幸福指数整数部分为7的分组数据个数:15
 
 
 
 
 
 
import numpy as np
grouped.agg({'Happiness Score': np.mean, 'Happiness Rank': np.max})
 
 
 
 Happiness ScoreHappiness Rank
score group  
2 2.872000 158
3 3.706632 156
4 4.580159 137
5 5.531959 93
6 6.560379 44
7 7.356800 15
 
 
 
 
 
 
grouped['Happiness Score'].agg([np.mean, np.max, np.min, np.std])
 
 
 
 meanamaxaminstd
score group    
2 2.872000 2.905 2.839 0.046669
3 3.706632 3.995 3.006 0.248455
4 4.580159 4.971 4.033 0.253251
5 5.531959 5.995 5.007 0.329597
6 6.560379 6.983 6.003 0.290584
7 7.356800 7.587 7.119 0.146969
 
 
 
 
 
 
 
 
 
 
posted @ 2017-11-15 08:43  在路上-UP  阅读(280)  评论(0编辑  收藏  举报