数据分析和建模方面的大量编程工作都是用在数据准备上的:加载、清理、转换以及重塑。pandas和python标准库提供了一组高级的、灵活的、高效的核心函数和算法。
01
合并数据集
- pandas.merge可根据一个或多个键将不同DataFrame中的行连接起来。SQL或其他关系型数据库对此思维应用比较常见。
- pandas.concat可以沿着一条轴将多个对象堆叠在一起。
- 实例方法combine_first可以将重复数据编接在一起,用一个对象中的值填充另一个对象中的缺失值。
1 数据库风格的DataFrame合并
- 数据集的合并(merge)或连接(join)运算是通过一个或多个键将行链接起来的。这些运算是关系型数据的核心。pandas的merge函数是对数据应用这些算法的主要切入点。
pd.merge(df1,df2,on = 'key') pd.merge(df1,df2) #如果没有指定,merge会将重叠列的列名当做键,最好显示指定一下。pd.merge(df1,df2,left_on = 'key1',right_on = 'key2' # 如果两个对象的列名不同,可以分别进行指定
- 默认情况下,merge做的是“inner”连接,结果中的键是交集。其他方式还有“left”、“right”、“outer”。外连接求取的是键的并集,组合了左连接和右连接的效果。
- 多对多的合并操作非常简单,无需额外的操作。多对多的连接产生 的是行的笛卡尔积,左边b行,右边a行,结果中就有a*b行。连接方式只影响出现在结果中的键。
- 要根据多个键进行合并,传入一个由列名组成的列表即可。结果中会出现哪些键的组合取决于所选的合并方式,也可以这样理解:多个键形成一系列元组,并将其当作单个连接键(实际上并不是这么回事)
- 合并运算需要考虑的最后一个问题是对重复列名的处理。虽然可以手动更改,但是merge有一个更实用的suffixes选项,用于指定附加到左右两个DataFrame对象的重叠列名上的字符串。
pd.merge(left,right,on = 'key'pd.merge(left,right,on = 'key1',suffixes = ('_left','_right'))
- merge函数的参数:
- left # 用于合并的左侧DataFrame
- right # 用于合并的右侧DataFrame
- how # “inner”、“outer”、“left”、‘“right”其中之一,默认 为“inner”
- on # 用于连接的列名
- left_on、tight_on # 左右侧DataFrame分别指定键
- left_index、right_index # 左右侧将索引用作连接键
- sort# 合并后进行排序,默认为True,处理大数据时,最好禁用
- suffixes # 字符串元组,用于追加到重叠列名的结尾,默认为“_x”、“_y”
- copy # 默认为Flase,可以在某种特殊情况下禁用,默认总是复制。
2 索引上的合并
- 有时候,DataFrame中的连接键位于其索引中,这种情况下,可以传入left_index、right_index = True,或两个都传以说明索引应该被用作连接键。
- 对于层次化索引的数据,必须以列表的形式指明用作合并键的多个列(注意对重复索引值的处理),同时使用合并双方的索引也没问题。
pd.merge(lefth,righth,left_on = ['key1','key2'],right_index = True)
DataFrame还有一个join实例方法,可以更为方便地实现按索引合并。还可以用于合并多个带有相同或相似索引的DataFrame对象,而不管它们有没有之间有没有重叠的列。
3 轴向连接
- 另一种数据合并运算也被称作连接(concatenation)、绑定(binding)或堆叠(stacking)。Numpy有一个用于合并原始Numpy数组的concatenation函数。
- pandas的concat函数提供了一种能够解决用于连接的轴、对结果对象中的分组,因索引不同造成的交并集结果等问题。
- concat函数的参数:
① objs # 参与连接的pandas对象,唯一必要的参数
② axis # 指明连接的轴向,默认为0
③ join # “inner”、“outer”其中之一,默认为“outer”
④ koin_axes # 指明用于其他N-1条轴的索引,不执行交并集运算
⑤keys 与连接对象有关的值,用于形成连接轴向上的层次化索引
⑥ levels # 指定用作层次化索引各级别上的索引
⑦ names # 用于创建分层级别的名称
⑧ verify_integrity # 检查结果对象新轴上的重复情况。默认允许(Flase)
⑨ ignore_index # 不保留连接轴上的索引,产生一组新的索引range
4 合并重叠数据
还有一种数据组合问题不能简单的用合并和连接运算来处理。
- Numpy的where函数,用于表达一种矢量化的if-elif-else
- Series的combine_first方法,实现相同的功能,而且会进行数据对齐
02
重塑和轴向旋转
有许多用于重新排列表格型数据的基础运算。这些函数也称作重塑(reshape)或轴向旋转(pivot)运算。
1 重塑层次化索引
- 层次化索引为DataFrame数据的重排任务提供了一种具有良好一致性的方式。主要功能有二:
- stack:将数据的列“旋转”为行
- unstack:将数据的行“旋转”为列
data.stack()data.stack.unstack()
- 使用stack方法可得到一个Series,对于一个层次化的Series,unstack的方式,可以得到一个DataFrame
- 默认情况下,stack和unstack操作的都是最内层,传入分层级别的编号或名称即可对其他级别进行unstack操作。
- 如果不是所有级别值都能在分组中找到,则返回缺失值
- stack默认过滤缺失值,运算可逆
- 对DataFrame进行unstack操作时,作为旋转轴的级别将会成为结果中的最低级别。
2 将“长格式”转换为“宽格式”
- 时间序列数据通常是以所谓的“长格式”或“堆叠格式”存储在数据库和CSV中的,关系型数据库中的数据尤其如此。
- 一方面保存数据的完整性,
- 另一方面便于查询支持。
- 但缺点是长格式的数据操作起来不轻松,可以用DataFrame中的pivot方法实现这个转换。
pivoted = ldata.pivot('date','item','value')
- 前两个参数分别用作行和列索引的列名,最后一个参数值则是用于填充DataFrame的数据列的列名。
- 如果有两个需要重塑的数据列或者忽略最后一个参数,返回的都是层次化的列。
- pivot只是一个快捷方式,用set_index创建层次索引,再用unstack重塑。
03
数据转换
数据不仅需要重排,也需要过滤、清理以及其他的转换等工作。
1 移除重复数据
- duplicates() 返回一个布尔型的Series,表示各行是否是重复行
- drop_duplicates() 返回一个移除了重复行的DataFrame
- 这两个方法默认会判断全部列,也可以指定部分列进行重复项判断。
- duplicates() 和drop_duplicates() 默认保留第一个出现的值组合,传入take_last = True则保留最后一个。
2 利用函数或映射进行数据转换
Series的map方法可以接受一个函数或含有映射关系的字典对象,map是一宗实现元素级转换以及其他数据清理工作的便捷方式。
3 替换值
- 利用fillna方法填充缺失数据可以看做值替换的一种特殊情况,虽然map可以修改对象的数据子集,但replace提供了一种跟简单、更灵活的方式。
data.replace(a,'b')data.replace(['a','c'],'b')data.replace(['a','c'],['b','d'])
- 传入的参数也可以是字典。
4 重命名轴索引
跟Series一样,轴标签也可以通过函数或映射进行转换,从而得到一个新对象。轴还可以就地被修改,而无需新建一个数据结构。
data.index.map(str.upper)
- 如果想要创建数据集的转换版(而不是修改原始数据),比较实用的方法是rename
data.rename(index = str.title,columns = str.upper) # 可以结合字典对象
5 离散化和面元划分
- cut函数
- 为了便于分析,连续数据常常被离散化或拆分为“面元”。要实现这个功能,需要pandas的cut函数
- pandas返回的是一个特殊的Categorical对象。可以将其看作一组表示面元名称的字符串,含有一个表示不同分类名称的levels数组 以及一个为年龄数据进行标号的labels的属性。
- 跟区间的符号一样,圆括号表示开端,方括号表示闭端,哪边是闭端可以通过tight = Flase控制。
- 如果向cut传入的面元的数量而不是确切的面元边界,则它会根据最小值和最大值计算一个等长面元,均匀分组。
ages = [20,22,25,27,21,23,37,23,23,54,26,29]bins = [18,25,35,60,100]cats = pd.cut(ages,cuts)catscats.labelscats.levelspd.cut(data,4,precision = 2)
- qcut函数
- qcut是一个非常类似于cut的函数,它可以根据样本分位数对数据进行面元划分,可以设置自定义的分位数(0~1之间,包含端点)
6 检测和过滤异常值
data[data['a'] >= 2].any(1)data[data['a'] == 2] = 3
7 排列和随机采样
利用numpy.random.permutation函数实现对Series和DataFrame的列的排列工作。
8 计算指标/哑变量
另一种常用于统计建模或机器学习的转换方式为:将分类变量转换为“哑变量”或“指标矩阵”
04
字符串操作
1 字符串对象方法
- Python内置的字符串方法
- count # 返回子串在字符串中的出现次数
- endswith/startswith # 如果字符串以某个后缀结尾或某个前缀开头,返回True
- join # 将字符串用作连接到其他字符串序列的分隔符
- index # 如果在字符串中找到子串,则返回子串第一个字符所在的 位置
- find # 如果在字符串中找到子串,则返回第一个发现的子串第一个字符所在的位置
- rfind # 如果在字符串中找到子串,则返回第一个发现的子串最后一个字符所在的位置
- replace # 用另一个字符串替换指定字符串
- strip、strip、lstrip # 去除空白符(包括换行符)
- split # 通过指定的分隔符将字符串拆分为一组子串
- lower、upper # 分别将字母字符转换为大小写
- ljust、rjust # 用空格填充字符串的空白侧 以返回符合最低宽度的字符串
2 正则表达式
3 pandas中矢量化的字符串函数