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赵六市场部NaNNaN
 
 
 
 
 
 
# 如果两个数据中包含有相同的列名(不是要合并的列)时,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赵六市场部上海NaNNaNNaN
 
 
 
 
 
 
# 也可指定后缀名称
pd.merge(staff_df, student_df, how='left', left_on='员工姓名', right_on='学生姓名', suffixes=('(公司)', '(家乡)'))
 
 
 
 员工姓名部门地址(公司)学生姓名专业地址(家乡)
0张三研发部天津张三计算机天津
1李四财务部北京李四会计上海
2赵六市场部上海NaNNaNNaN
 
 
 
 
 
 
# 也可以指定多列进行合并,找出同一个人的工作地址和家乡地址相同的记录
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
0SwitzerlandWestern Europe17.5870.034111.396511.349510.941430.665570.419780.296782.51738
1IcelandWestern Europe27.5610.048841.302321.402230.947840.628770.141450.436302.70201
2DenmarkWestern Europe37.5270.033281.325481.360580.874640.649380.483570.341392.49204
3NorwayWestern Europe47.5220.038801.459001.330950.885210.669730.365030.346992.46531
4CanadaNorth America57.4270.035531.326291.322610.905630.632970.329570.458112.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  
22.872000158
33.706632156
44.580159137
55.53195993
66.56037944
77.35680015
 
 
 
 
 
 
grouped['Happiness Score'].agg([np.mean, np.max, np.min, np.std])
 
 
 
 meanamaxaminstd
score group    
22.8720002.9052.8390.046669
33.7066323.9953.0060.248455
44.5801594.9714.0330.253251
55.5319595.9955.0070.329597
66.5603796.9836.0030.290584
77.3568007.5877.1190.146969
 
 
 
 
 
 
 
 
 
 

转载于:https://www.cnblogs.com/crawer-1/p/7837204.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值