Python数据分析入门笔记7——数据集成、变换与规约(很长的笔记,留作工具书查阅)

系列文章目录


Python数据分析入门笔记1——学习前的准备

Python数据分析入门笔记2——pandas数据读取

Python数据分析入门笔记3——数据预处理之缺失值

Python数据分析入门笔记4——数据预处理之重复值

Python数据分析入门笔记5——数据预处理之异常值

Python数据分析入门笔记6——数据清理案例练习


前言

本文需要数据库基础知识。涉及到表、主键、连接、分组等内容。
本文只做笔记用,常用的其实只有merge、groupby还有apply这几个。
在这里插入图片描述


一、数据集成

1. 【重点】主键合并数据——merge()函数

merge()函数用于根据一个或多个键连接两组数据

merge(left,right,how=‘inner’,on=None,left_on=None,right_on=None,left_index=False,right_index=False,sort=False,sumfflxes=‘_x’,‘_y’,copy=True,indicator=False,validate=None)

参数名说明
left、right表示参与合并的Series类对象或DataFrame类对象
how表示数据合并的方式,取值:'inner’内连接,'left’左外连接,'right’右外连接,'outer’全外连接。
on表示left与right合并的键,也就是用哪个键来连接两个对象
left_on表示将left中列索引作为键
right_on表示将right中列索引作为键
left_index表示将left中行索引作为键
right_index表示将right中行索引作为键
sort表示按键对应列的顺序对合并结果进行排序,默认为True

例如,有学生基础信息表和成绩单如下:
左表是学生信息表,有学号1、2、3三个人

学号姓名年龄
1张大16
2张二15
3张三14

右表是学生成绩表,主键是学号,有学号为1、2、4的三个学生的语文、数学和英语成绩

学号语文数学英语
1908988
2888786
4787776

用如下代码合并:

import pandas as pd
df_left=pd.DataFrame({'学号':['1','2','3'],
                      '姓名':['张大','张二','张三'],
                      '年龄':[16,15,14]})
df_right=pd.DataFrame({'学号':['1','2','4'],
                       '语文':[16,15,14],
                       '数学':[16,15,14],
                       '英语':[16,15,14]})
# 以学号为主键,采用内连接的方式合并数据
result_inner=pd.merge(df_left,df_right,how='inner',on='学号')
print(result_inner)

运行结果:

附另外三种连接方式的代码和运行结果:
在这里插入图片描述

2. 堆叠合并数据——concat()函数

concat()函数用于数据集的合并,类似于关系数据库中的join。

concat(objs, axis=0, join=‘outer’, join_axes=None, ignore_index=False, keys=None, levels=None, names=None, verify_integrity=False, sort=None, copy=True)

参数名说明
objs表示参与合并的Series类对象或DataFrame类对象列表,如[df_left, df_right]
axis表示要合并的轴,取值可以为0或‘index’,表示沿着行方向的轴合并数据;也可以为1或‘columns’,表示按列合并。默认为0。
join表示合并方式,取值:‘inner‘或’outer’。默认为outer。
ignore_index是否忽略索引,True或False,默认为False。True意为清除现有索引后重新生成新索引。

例如,有学生基础信息表和成绩单如下:
左表是一班学生信息表,有学号1、2、3三个人

学号姓名年龄
1张大16
2张二15
3张三14

右表是二班学生信息表,有学号11、12和14三个人

学号姓名性别
11李大
12李二
14李四

用如下代码合并:

df_left=pd.DataFrame({'学号':['1','2','3'],
                      '姓名':['张大','张二','张三'],
                      '年龄':[16,15,14]})
df_right=pd.DataFrame({'学号':['11','12','14'],
                       '姓名':['李大','李二','李四'],
                       '性别':['男','男','男']})
# 默认采用外连接的方式逐行堆叠,可理解为两个班名单直接合并
result_concat=pd.concat([df_left,df_right],axis=0)
print(result_concat)

运行结果:
在这里插入图片描述

3. 重叠合并数据——combine_first()函数

重叠合并数据并不常用。是指当两组数据的索引完全重合或部分重合,且数据中存在缺失值时,可以采用重叠合并的方式组合数据,能将一组数据的空值填充为另一组数据中对应位置的值。

combine_first(other)

这里要注意两个问题,这两组数据的索引,最好完全重合,因为这个合并非常不智能,不会像连接一样还去对一下主键,是直接无脑复制粘贴。
所以,能不用就不用吧!!!!!!
示例代码如下:
若有两个表,都只有这三个兄弟,表1里缺性别信息,表2里缺年龄,那combine一下,大家就都有了。

import numpy as np
df_left=pd.DataFrame({'学号':['1','2','3'],
                      '姓名':['张大','张二','张三'],
                      '年龄':[16,15,14],
                      '性别':[np.nan,np.nan,np.nan]})
df_right=pd.DataFrame({'学号':['1','2','3'],
                       '姓名':['张大','张二','张三'],
                       '性别':['男','男','男']})
result_combine=df_left.combine_first(df_right)
print(result_combine)

在这里插入图片描述

二、数据变换

进行分析或挖掘的数据,必须提前满足一定条件。
如,进行方差分析时要求数据具有正态性、方差齐性、独立性、无偏性,需进行诸如平方根、对数、平方根反正弦的操作,实现一种形式到另一种适当形式的转换,以满足数据分析或数据挖掘的需求,这一过程就是数据变换。

(一)轴向旋转

1. pivot()方法

DataFrame.pivot(index=None, columns=None, values=None)

参数名说明
index想以哪一列作为新对象的行索引?
columns新对象打算用哪一列作为索引?
values哪一列是值?

若有表格内容如下:

序列商品名称出售日期价格(元)
0荣耀9X5月25日999
1小米6X5月25日1399
2OPPO A15月25日1399
3荣耀9X6月18日800
4小米6X6月18日1200
5OPPO A16月18日1250

现在想以“出售日期”为列索引,“商品名称”中的值作为列标题,展示不同产品6.18降价情况。可以用如下代码实现:

import pandas as pd
df_obj=pd.DataFrame({'商品名称':['荣耀9X','小米6X','OPPO A1','荣耀9X','小米6X','OPPO A1'],
                    '出售日期':['5月25日','5月25日','5月25日','6月18日','6月18日','6月18日'],
                     '价格(元)':[999,1399,1399,800,1200,1250]
                    })
print(df_obj)
# 将“出售日期”一列的唯一值变换为行索引,“商品名称”一列的唯一值变换为列索引
new_df=df_obj.pivot(index='出售日期',columns='商品名称',values='价格(元)')
print(new_df)

运行结果如图:
在这里插入图片描述

2. melt()方法——是pivot方法的逆操作

DataFrame.melt(id_vars=None, value_vars=None, var_name=None, value_name=‘value’, col_level=None, ignore_index=True)

参数名说明
id_vars表示无需被转换的列索引
value_vars表示待转换的列索引。默认全部转换。
var_name表示自定义的列索引
value_name表示自定义的数据所在列的索引
col_level表示列索引的级别。若列索引是分层索引,则可使用此参数
ignore_index表示是否忽略索引,默认为True

若要将刚刚的表格,恢复原来的样子,可用如下代码:

# 将列索引转换为一行数据
new_df.melt(value_name='价格(元)', ignore_index=False)

运行结果如图:在这里插入图片描述

(二)【重点】 分组与聚合

在这里插入图片描述

1. 分组操作——groupby()

groupby(by=None, axis=0, level=None, as_index=True, sort=True, group_key=True, squeeze=< object object>, observed=False, dropna=True)

参数名取值说明
by表示分组条件
axis0或1表示分组操作的轴编号,默认为0,沿列操作
level默认None表示标签索引所在的级别
as_index默认True表示聚合后新数据的索引是否为分组标签的索引
sort默认True表示是否对分组索引进行排序
group_keys默认True表示是否显示分组标签的名称
import pandas as pd
df_obj=pd.DataFrame({"key":["C","B","C","A","B","B","A","C","A"],
                     "data":[2,4,6,8,10,1,3,5,7]
                    })
# 根据key列对df_obj进行分组
groupby_obj=df_obj.groupby(by="key")

# 此处必须注意,groupby操作后得到的数据是很多元组,需要for循环遍历才能看到每个分组中的内容
for group in groupby_obj:
    print(group)

运行结果如下:
在这里插入图片描述
若只想输出制定元组内容,可先转换为字典再输出。

result= dict([x for x in  groupby_obj])['A']
print(result)

在这里插入图片描述

2. 聚合操作——agg()、transform()和apply()

可直接用内置的统计方法,如可以直接用groupby_obj.max()来统计每个分组中的最大值。

print(group_obj.max())

在这里插入图片描述

(1)agg()
(2)transform()
(3)【常用】apply()

示例:将groupby_obj对象中的每个数据变为该数据除以100后的结果。
需要先自定义一个函数,用来求某数据除以100后所得结果,再利用apply方法将该函数应用到各分组。

# 先定义一个DataFrame对象,这里复用之前的数据
df_right=pd.DataFrame({'学号':['1','2','4'],
                       '语文':[90,89,88],
                       '数学':[88,87,86],
                       '英语':[78,77,76]})
# 按学号分组,并逐个输出
groupby_obj=df_right.groupby(by='学号')
for group in groupby_obj: 
    print(group)

# 自定义函数,命名为div_hun,若要将成绩都转化为[0,1]之间的数,就需要对对象中的每个数都做/100的操作。
def div_hun(df):
    return df.iloc[:,:]/100
# 用apply方法可以直接将自定义函数应用到各分组中 
print(groupby_obj.apply(div_hun))

运行结果如下:
在这里插入图片描述

(三)哑变量处理——get_dummies()函数

简单来说,哑变量处理就是将类别数据进行“量化”处理。
哑变量,又称虚拟变量,是人为虚设的变量,用来反映某个变量的不同类别,常用取值为0和1,0代表否,1代表是。
示例:

import pandas as pd
position_df=pd.DataFrame({'职业':['工人','学生','司机','教师','导游']})
# 哑变量处理,并给哑变量添加前缀
result=pd.get_dummies(position_df,prefix=['col'])
print(result)

在这里插入图片描述

(四)面元划分——cut()函数

面元划分是指数据被离散化处理,按一定的映射关系划分为相应的面元(可理解为区间),只适用于连续数据。

示例:某电商平台统计了一组关于客户年龄的数据,划分面元代码如下:

import pandas as pd
ages=pd.Series([19,21,25,55,30,45,52,46,20])
bins=[0,18,30,40,50,100]
# 使用cut()函数划分年龄区间
cuts=pd.cut(ages,bins)
print(cuts)

在这里插入图片描述

三、数据规约——针对大型数据集

(一)重塑分层索引——stack()

示例:

import pandas as pd
df=pd.DataFrame({'A':['A0','A1','A2'],
                'B':['B0','B1','B2']})
# 重塑df,使之具有两层行索引
result=df.stack()
print(result)

在这里插入图片描述

(二)降采样——resample()

顾名思义,降采样就是降低采样频率,即将高频率采集的数据规约到低频率采集的数据,常用于时间序列类型的数据。如原来每天一采集改为三天一采集。


示例:
import pandas as pd
import numpy as np
# 生成一个时间序列,从2020年6月1日开始,跨度为30天
time_ser=pd.date_range('2020/06/01',periods=30)
# 生成一个含30个随机数的序列,范围40到60之间
stock_data=np.random.randint(40,60,size=30)
# 创建一个Series对象
time_obj=pd.Series(stock_data,index=time_ser)
print(time_obj)

#每7天采集一次数据,实现降采样操作,并且用相同周期内的平均值保证数据的准确与精简
result=time_obj.resample('7D').mean()
result.astype("int64")

在这里插入图片描述

总结

暂时学到了这里,其他内容用到了再回来更。。。
参考资料:《Python数据预处理》,黑马程序员编著,人民邮电出版社出版

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值