内容简介:Python基础数据处理库-Pandas
最近更新:2018-01-11
pandas是 Python 数据工作的基础库之一,它和numpy、scipy共成为Python数据处理的三剑客。pandas在数据录入、查看、预处理、统计分析、时间序列等方面具有非常强大的能力。尤其它里面的数据框跟R中的数据框类似,其具有的交互性以及对非结构化、非数值型数据的处理能力让Python的基础数据处理事半功倍。
1、Pandas读取数据文件
相对于Python默认函数以及Numpy读取文件的方法,Pandas读取数据的方法更加丰富。Pandas读取文本文件数据的常用方法如下表:
方法 | 描述 | 返回数据 |
read_csv | 读取csv文件 | DataFrame 或TextParser |
read_fwf | 读取表格或固定宽度格式的文本行到数据框 | DataFrame 或TextParser |
read_table | 读取通用分隔符分隔的数据文件到数据框 | DataFrame 或TextParser |
1.1 使用read_cvs方法读取数据
通过read_csv方法可以读取csv格式的数据文件。
read_csv(filepath_or_buffer, sep=',', delimiter=None, header='infer', names=None, index_col=None, usecols=None, **kwds)
参数(read_csv的参数众多,以下介绍最常用的几个参数):
- filepath_or_buffer:字符串,要读取的文件对象,必填。
- sep:字符串,分隔符号,选填,默认值为英文逗号','。
- names:类数组,列名,选填,默认值为空。
- skiprows:类字典或整数型,要跳过的行或行数,选填,默认为空。
- nrows:整数型,要读取的前记录总数,选填,默认为空,常用来在大型数据集下做初步探索之用。
- thousands:字符串,千位符符号,选填,默认为空。
- decimal:字符串,小数点符号,选填,默认为点(.),在特定情况下应用,例如欧洲的千位符和小数点跟中国地区相反,欧洲的321,1对应中国的4,321.1。
1.2 使用read_ fwf 方法读取数据
通过read_fwf方法可以读取表格或固定宽度格式的文本行到数据框。
read_fwf(filepath_or_buffer, colspecs='infer', widths=None, **kwds)
参数
read_fwf跟read_csv一样都具有非常多的参数(只是在语法中前者通过**kwds省略了,查询完整语法请使用help(pd.read_fwf)),并且大多数参数的用法相同。除了read_csv中的常用参数外,以下介绍几个read_fwf特有且常用的参数。
widths:由整数组成的列表,选填,如果间隔是连续的,可以使用的字段宽度列表而不是“colspecs”。
1.3 使用read_ table 方法读取数据
通过read_table方法可以读取通用分隔符分隔的数据文件到数据框。
read_table(filepath_or_buffer, sep='\t', delimiter=None, header='infer', names=None, index_col=None, usecols=None, **kwds)
对于read_table而言,参数与read_csv完全相同。其实read_csv本来就是read_table中分隔符是逗号的一个特例,表现在语法中是read_csv的sep=','(默认)。因此,具体参数请查阅read_csv的参数部分。
Pandas其他数据读取方法
方法 | 描述 | 返回数据 |
read_clipboard | 读取剪贴板数据,然后将对象传递给read_table方法 | DataFrame 或TextParser |
read_excel | 从excel中读取数据 | DataFrame或DataFrame构成的字典 |
read_gbq | 从Google Bigquery中读取数据 | DataFrame |
read_hdf | 读取文件中的Pandas对象 | 所选择的数据对象 |
read_html | 读取HTML中的表格 | 由DataFrame构成的字典 |
read_json | 将JSON对象转换为Pandas对象 | Series或 DataFrame,具体取决于参数typ设置 |
read_msgpack | 从指定文件中加载msgpack Pandas对象 | 文件中的对象类型 |
read_pickle | 从指定文件中加载pickled Pandas或其他pickled对象 | 文件中的对象类型 |
read_sas | 读取XPORT或SAS7BDAT格式的SAS(统计分析软件)文件 | DataFrame或SAS7BDATReader或XportReader,具体取决于设置 |
read_sql | 读取 SQL 请求或数据库中的表 | DataFrame |
read_sql_query | 从SQL请求读取数据 | DataFrame |
read_sql_table | 读取SQL数据库中的表 | DataFrame |
read_stata | 读取Stata(统计分析软件)文件 | DataFrame或StataReader |
如何选择最佳读取数据的方法
关于“最佳”方法其实没有固定定义,因此所谓的最佳方法往往跟以下具体因素有关:
- 数据源情况:数据源中不同的字段类型首先会制约读取方法的选择,文本、数值、二进制数据都有各自的适应方法约束。
- 数据处理目标:读取数据往往是第一步,后续会涉及到数据探索、预处理、统计分析等复杂过程,这些复杂过程需要用到哪些方法都会一定程度上受数据源的读取影响,影响最多的点包括格式转换、类型转换、异常值处理、分类汇总等。
- 模型数据要求:不同的模型对于数据格式的要求是不同的,应用到实际中不同的 工具 对于数据的表示方法也有所差异。
- “手感”最好的方法:很多时候,最佳方法往往是对哪个或哪些方法最熟悉,这些所谓的“手感”最好的方法便是最佳方法。
当然,即使使用了不是“最佳”的数据读取方法也不必过于担心,因为Python强大的功能提供了众多可以相互进行转换的方法,从Python存储数据的基本对象类型来看,无非是字符串、列表、字典、元组、数组、矩阵等(当然不同的库对于这些对象的定义名称可能有所不同,但基本含义相同),不同对象的类型转换都非常容易。但本着少走弯路的原则,在这里笔者还是针对不同的场景提供了较为适合的数据读取方法:
- 对于纯文本格式或非格式化、非结构化的数据,通常用于自然语言处理、非结构化文本解析、应用正则表达式等后续应用场景下,Python默认的三种方法更为适合。
- 对于结构化的、纯数值型的数据,并且主要用于矩阵计算、数据建模的,使用Numpy的loadtxt更为方便,例如本书中使用的sklearn本身就依赖于Numpy。
- 对于二进制的数据处理,使用Numpy的load和fromfile更为合适。
- 对于结构化的、探索性的数据统计和分析的场景,使用Pandas进行读取效果更佳,因为其提供了类似于R的数据框,可以实现“仿SQL”式的操作方式,对数据进行任意的翻转、切片(块等)、关联等都非常方便。
- 对于结构化的、数值型和文本型组合的数据统计分析场景,使用Pandas更为合适,因为每个数据框中几乎可以装载并处理任意格式的数据。
2、Pandas缺失值处理
先生成带有缺失值的模拟数据:
import pandas as pd # 导入pandas库 import numpy as np # 导入numpy库 df = pd.DataFrame(np.random.randn(6, 4), columns=['col1', 'col2', 'col3', 'col4']) # 生成一份数据 df.iloc[1:2, 1] = np.nan # 增加缺失值 df.iloc[4, 3] = np.nan # 增加缺失值 print (df)
示例数据结果中如下 :
col1 col2 col3 col4 0 -0.424315 1.024795 0.665549 0.721605 1 -0.502295 NaN -0.147179 -0.150555 2 0.009386 0.490898 -0.128985 0.013604 3 -0.395965 0.792293 -1.416035 -0.261842 4 -0.218898 0.273137 -0.547399 NaN 5 -0.029000 -1.773710 1.190229 -1.451912
2.1 Pandas查看缺失值
2.1.1 查看哪些值缺失
# 查看哪些值缺失 nan_all = df.isnull() # 获得所有数据框中的NA值 print (nan_all) # 打印输出
详细缺失值结果如下:
col1 col2 col3 col4 0 False False False False 1 False True False False 2 False False False False 3 False False False False 4 False False False True 5 False False False False
2.1.2 查看哪些列具有缺失值
# 查看哪些列缺失 nan_col1 = df.isnull().any() # 获得含有NA的列 nan_col2 = df.isnull().all() # 获得全部为NA的列 print (nan_col1) # 打印输出 print (nan_col2) # 打印输出
上面的方法中,第一个方法是查看所有列中,只要有一个值为NA的;在any方法中,还可以加入对行或列的判断,例如:
any(axis=0):用于判断以列为单位的缺失值,如果一列中存在任何一个缺失值则为True。 any(axis=1):用于判断以行为单位的缺失值,如果一行中存在任何一个缺失值则为True。
第二个方法是查看所有列都为NA的,结果如下:
col1 False col2 True col3 False col4 True dtype: bool col1 False col2 False col3 False col4 False dtype: bool
2.2 Pandas丢弃缺失值
df2 = df.dropna() # 直接丢弃含有NA的行记录 print (df2) # 打印输出
输出结果如下:
col1 col2 col3 col4 0 -0.424315 1.024795 0.665549 0.721605 2 0.009386 0.490898 -0.128985 0.013604 3 -0.395965 0.792293 -1.416035 -0.261842 5 -0.029000 -1.773710 1.190229 -1.451912
所有带有缺失值的行记录被删除
pandas支持按行或列做删除,例如删除带有缺失值的列,并且以指定所有数据都是NA还是只有一个值为NA。指定按行/列删除用axis参数,指定NA是含有任意一个还是全部都是NA使用how参数。具体用法如下:
df.dropna(axis=1, how='all')
其中:
axis取值为0 ('index')或1 ('columns')
how取值为'any'或'all'
2.2 Pandas填充缺失值
pandas填充缺失值有很多种方法:
# 使用pandas将缺失值替换为特定值 nan_result_pd1 = df.fillna(method='backfill') # 用后面的值替换缺失值 nan_result_pd2 = df.fillna(method='bfill', limit=1) # 用后面的值替代缺失值,限制每列只能替代一个缺失值 nan_result_pd3 = df.fillna(method='pad') # 用前面的值替换缺失值 nan_result_pd4 = df.fillna(0) # 用0替换缺失值 nan_result_pd5 = df.fillna({'col2': 1.1, 'col4': 1.2}) # 用不同值替换不同列的缺失值 nan_result_pd6 = df.fillna(df.mean()['col2':'col4']) # 用平均数代替,选择各自列的均值替换缺失值 # 打印输出 print (nan_result_pd1) # 打印输出 print (nan_result_pd2) # 打印输出 print (nan_result_pd3) # 打印输出 print (nan_result_pd4) # 打印输出 print (nan_result_pd5) # 打印输出 print (nan_result_pd6) # 打印输出
填充后的结果如下:
col1 col2 col3 col4 0 -0.424315 1.024795 0.665549 0.721605 1 -0.502295 0.490898 -0.147179 -0.150555 2 0.009386 0.490898 -0.128985 0.013604 3 -0.395965 0.792293 -1.416035 -0.261842 4 -0.218898 0.273137 -0.547399 -1.451912 5 -0.029000 -1.773710 1.190229 -1.451912 col1 col2 col3 col4 0 -0.424315 1.024795 0.665549 0.721605 1 -0.502295 0.490898 -0.147179 -0.150555 2 0.009386 0.490898 -0.128985 0.013604 3 -0.395965 0.792293 -1.416035 -0.261842 4 -0.218898 0.273137 -0.547399 -1.451912 5 -0.029000 -1.773710 1.190229 -1.451912 col1 col2 col3 col4 0 -0.424315 1.024795 0.665549 0.721605 1 -0.502295 1.024795 -0.147179 -0.150555 2 0.009386 0.490898 -0.128985 0.013604 3 -0.395965 0.792293 -1.416035 -0.261842 4 -0.218898 0.273137 -0.547399 -0.261842 5 -0.029000 -1.773710 1.190229 -1.451912 col1 col2 col3 col4 0 -0.424315 1.024795 0.665549 0.721605 1 -0.502295 0.000000 -0.147179 -0.150555 2 0.009386 0.490898 -0.128985 0.013604 3 -0.395965 0.792293 -1.416035 -0.261842 4 -0.218898 0.273137 -0.547399 0.000000 5 -0.029000 -1.773710 1.190229 -1.451912 col1 col2 col3 col4 0 -0.424315 1.024795 0.665549 0.721605 1 -0.502295 1.100000 -0.147179 -0.150555 2 0.009386 0.490898 -0.128985 0.013604 3 -0.395965 0.792293 -1.416035 -0.261842 4 -0.218898 0.273137 -0.547399 1.200000 5 -0.029000 -1.773710 1.190229 -1.451912 col1 col2 col3 col4 0 -0.424315 1.024795 0.665549 0.721605 1 -0.502295 0.161482 -0.147179 -0.150555 2 0.009386 0.490898 -0.128985 0.013604 3 -0.395965 0.792293 -1.416035 -0.261842 4 -0.218898 0.273137 -0.547399 -0.225820 5 -0.029000 -1.773710 1.190229 -1.451912
3、Pandas数据切片/切块/筛选/过滤
3.1 通过列名选择特定列
# 生成数据 df = pd.DataFrame({'id': [3566841, 6541227, 3512441], 'sex': ['male', 'Female', 'Female'], 'level': ['hight', 'low', 'middle']}) # 建立针对特定列名的列表并过滤数据 col_name = ['id','sex'] col_data = df[col_name] # 获得每列数据 print(col_data)
过滤后的数据如下:
id sex 0 3566841 male 1 6541227 Female 2 3512441 Female
在针对列名的过滤中,如果过滤单一列,COL_NAME可以是字符串,也可以是由一个字符串组成的列表。但前者过滤后是一个series,后者过滤后是一个DataFrame,二者在后续的操作上会有差异。
3.2 通过列名属性的选择方法选择特定列数据
Pandas提供了直接通过属性选择列值的方法,格式为:
# 使用列名做为属性选择特定列数据 df.sex
上面代码返回如下结果:
0 male 1 Female 2 Female Name: sex, dtype: object
注意:这种操作方法需要对DataFrame已经做过列命名,如果创建数据框时没有定义列名(例如使用默认的index),那么这种操作方法是不可行的。
3.3 通过loc方法选择列数据或切块数据
Pandas提供了loc方法选择特定数据,格式为:
# df.loc[index1:index2,[col1,col2]] df.loc[0:1,['id','sex']] # 选择前2行以及id和sex列数据
上面代码返回如下结果:
id sex 0 3566841 male 1 6541227 Female
其中:index1和index2为行索引值(注意从0开始);col1、col2等是列名,如果要选择所有列,按脉直接使用:即可,例如df.loc[0:1,:]
3.4 通过iloc方法选择列数据或切块数据
Pandas提供了iloc方法可以灵活的选择特定数据,它的用法跟loc基本一致,但二者的区别在于loc方法中,可以通过列名选择数据,而iloc只能通过列索引值选择数据,格式为:
# df.loc[index1:index2,col_index1,col_index2]] df.loc[0:1,0:1] # 选择前2行以及id和sex列数据
上面代码返回如下结果:
- id
- 41
其中:index1和index2为行索引值(注意从0开始);col_index1、col_index2是列索引名
3.5 通过ix方法选择数据
Pandas提供了ix方法,这个方法可以看成是iloc和loc的结合体,由于它结合了二者的用法,在做列选取时即可使用索引值,也可以使用列名标签。因此是实用性最广的灵活选择方法。格式为:
df.ix[0:1,0:1] # 索引选择 df.ix[0:1,['id']] # 列名选择
以上两种写法是等效的,上面代码返回如下结果:
id 0 3566841 1 6541227
总结
- 在官方的建议中,不建议使用ix方法。
- 对于列名类的选择,建议使用的是loc方法;
- 对于索引类的选择,建议使用的是iloc方法;
- 对于单纯列(单列或多列)的选择,使用属性的方法选择单列最简单,但列名方法却更实用,因此它可以灵活定义可变列。
4、Pandas字符串与日期转换和解析
pandas中的datetime库是处理与日期相关主要功能库,其中的strftime用来将字符串解析为日期格式,与strptime方法对应的是strftime方法,用来将日期转换为字符串。关于日期的格式,pandas采用的是python默认的日期格式,完整见https://docs.python.org/2/library/datetime.html#strftime-and-strptime-behavior。以下是常用的日期格式字符串如下:
表4-6 日期字符串
字符串 | 日期格式 | 示例 |
%y | 2个数字表示的年份 | 99 |
%Y | 4个数字表示的年份 | 1999 |
%b | 月份的简写 | Jan |
%B | 月份的全写 | January |
%m | 月份([01,12]) | 10 |
%a | 星期的简写 | Mon |
%A | 星期的全写 | Monday |
%w | 周几([0, 6])0表示周一,以此类推 | 5 |
%U | 当年的第几周,星期日作为周的第一天([00,53]) | 30 |
%W | 当年的第几周,星期一作为周的第一天([00,53]) | 30 |
%d | 日是这个月的第几天,范围[01,31] | 12 |
%p | AM或PM | AM |
%H | 小时(24小时制,[00, 23]) | 20 |
%I | 小时(12小时制,[01, 12]) | 12 |
%j | 日在年中的天数 [001,366] | 360 |
%M | 分钟([00,59]) | 59 |
%S | 秒([00,59]) | 59 |
%f | 微秒([000000,999999]) | 0 |
将字符串 转化为日期
# 定义一个时间字符串 date_str = '01-12-2017' date_formate = pd.datetime.strptime(date_str, '%m-%d-%Y') print(date_formate)
上述代码执行后,格式化的日期为:
2017-01-12 00:00:00
将日期转化为字符串
date_convert = pd.datetime.strftime(date_formate, '%Y-%m-%d') print(date_convert)
转换后的结果如下:
2017-01-12
实际上,由于该操作是针对单个字符串对象进行的,我们更多的会使用“批量”的方式做字符串格式解析,例如:
date_parse = lambda dates: pd.datetime.strptime(dates, '%m-%d-%Y') # 创建解析列的功能对象 df = pd.read_table('time_series.txt', delimiter='\t', index_col='date', date_parser=date_parse) # 读取数据
上述代码中,在使用pandas的read_table读取数据文件时,通过index_col指定date列为索引列,代替默认的数值索引;通过date_parser参数指定刚才定义的日期解析功能项。
5、Pandas基本数据查看
先创建一个demo数据框
cols = ['col_'+str(i) for i in range(3)] # 自定义列名 df = pd.DataFrame(np.arange(12).reshape(4,3),columns = cols) #创建数据框 df.iloc[1,1] = 'a' # 为了方便,我们将其中加入字符串数据 print(df) # 输出查看
示例数据如下:
col_0 col_1 col_2 0 0 1 2 1 3 a 5 2 6 7 8 3 9 10 11
5.1 描述性统计
使用describe方法查看,描述性统计结果:
df.describe()
结果如下:
col_0 col_2 count 4.000000 4.000000 mean 4.500000 6.500000 std 3.872983 3.872983 min 0.000000 2.000000 25% 2.250000 4.250000 50% 4.500000 6.500000 75% 6.750000 8.750000 max 9.000000 11.000000
结果发现,统计结果中,没有col_1的结果,原因是其中有一个字符串a。我们通过设置参数来查看所有列的情况:
df.describe(include='all')
这次返回结果如下:
col_0 col_1 col_2 count 4.000000 4.0 4.000000 unique NaN 4.0 NaN top NaN 7.0 NaN freq NaN 1.0 NaN mean 4.500000 NaN 6.500000 std 3.872983 NaN 3.872983 min 0.000000 NaN 2.000000 25% 2.250000 NaN 4.250000 50% 4.500000 NaN 6.500000 75% 6.750000 NaN 8.750000 max 9.000000 NaN 11.000000
这次我们看到了出现了一些新的统计指标,包括unique、top、freq,这些是针对字符串列出现的新指标。
5.2 查看各列类型
在上面的示例中,我们已经发现,col_1无法做普通的描述性统计,这个问题其实在最开始可以通过查看dtype来发现。
查看所有列的属性
df.dtypes
返回结果如下:
col_0 int32 col_1 object col_2 int32 dtype: object
我们看到第2列是object属性,也就是字符串列。
5.3查看前n条数据
查看基本数据状态是非常常用的操作,要查看TOP N条数据,使用head方法,具体为:
df.head(n)
其中n是要查看的数据记录的数量,默认n为5。如果设置n为2,上述结果如下:
#df.head(2) col_0 col_1 col_2 0 0 1 2 1 3 a 5
5.4查看后n条数据
查看后n条数据跟前n条数据的用法类似,其方法是tail,具体为:
df.tail(n)
n默认也是5,如果设置2,那么后2条数据为:
#df.tail(2) col_0 col_1 col_2 2 6 7 8 3 9 10 11
5.5查看所有列名
通过columns查看所有列名
df.columns Index([u'col_0', u'col_1', u'col_2'], dtype='object')
5.6查看所有index
通过index查看所有index索引信息
df.index RangeIndex(start=0, stop=4, step=1)
6、数据基本处理
先生成一个demo数据:
# 生成数据 df = pd.DataFrame({'num': [12, 8, 2,1], 'sex': ['male', 'Female', 'Female','Female'], 'level': ['hight', 'low', 'middle','middle']})
6.1 分类汇总
分类汇总的基本格式为:
df.groupby(col_names1)[col_name2].function
-
其中:
- col_names1指的是分类的目标字段,例如对age做分类,那么这里需要写['age'];如果对多个字段做汇总,例如age和sex,那么需要分别填写['age','sex']
- col_name2指的是要计算的字段,例如对上述的age做汇总, 是基于哪个字段做计算,可能是收入、订单量或业务量
- function指的是汇总的方式,一般常用的是mean()、sum()、count()等
示例:
对sex列做统计,统计指标为num列,汇总方式为求和
df.groupby(['sex'])['num'].sum() # 查看 # 输出 sex Female 11 male 12 Name: num, dtype: int64
对sex列做统计,统计指标为level列,汇总方式为计数
df.groupby(['sex'])['level'].count() # 查看 # 输出 sex Female 3 male 1 Name: level, dtype: int64
对sex和level分别做统计,统计指标为num,汇总方式为均值
df.groupby(['sex','level'])['num'].mean() # 查看 # 输出 sex level Female low 8.0 middle 1.5 male hight 12.0 Name: num, dtype: float64
6.2 排序
pandas的 排序 使用的是sort_values方法,具体应用为:
df.sort_values(by='num', ascending=True)
其中,by后是要排序的列,ascending用来指定排序是正序(True)还是倒序(False)。上面方法排序后的输出为:
level num sex 3 middle 1 Female 2 middle 2 Female 1 low 8 Female 0 hight 12 male
6.3 查看替换
pandas中的replace方法是一个非常强大的字符串替换功能,它可以实现字符串、字典、列表、数字甚至正则表达式级别的转换。
语法:
replace(self, to_replace=None, value=None, inplace=False, limit=None, regex=False, method='pad', axis=None)
其中关键参数如下:
to_replace:要替换的对象。它可以是str、regex、list、dict、Series、numeric、None。
- str是完全替换和匹配的字符串。
- regex是匹配符合正则表达式模式的对象。
- list可以是字符串列表、正则表达式列表或数值列表。如果to_replace(原始对象)和value(替换后的对象)都是列表格式,那么列表长度必须一致;如果regex参数设置为True,那么两个列表中的所有字符串将被应用正则表达式。
- dict:可以使用嵌套字典直接做匹配模式定义,例如嵌套字典({'a':{'b':nan}})将在列'a'中查找值'b',并将其替换为nan,嵌套中也可以使用正则表达式。
value:替换后的值。它也可以是scalar、dict、list、str、regex,其中dict对象可以将每个列指定为不同的替换值,例如{'a':1,'b':2}可以将列a替换为1,列b替换为2。
示例
df.replace('male','m') # 将字符串male替换为m # 替换后的结果 level num sex 0 hight 12 m 1 low 8 Female 2 middle 2 Female 3 middle 1 Female
6.4 数据框合并、组合、匹配
Pandas对数据框的合并、组合和匹配,主要有两种方式,一种是concat,一种是merge。
我们先生成一段示例数据:
col_names = ['col_' + str(i) for i in range(3)] # demo数据的列名 df1 = pd.DataFrame(np.arange(12).reshape(4,3),columns=col_names) # 第一份demo数据 df2 = pd.DataFrame(np.arange(12,24).reshape(4,3),columns=col_names) # 第二份demo数据 print(df1) # 打印输出 print(df2) # 打印输出
demo数据如下:
col_0 col_1 col_2 0 0 1 2 1 3 4 5 2 6 7 8 3 9 10 11 col_0 col_1 col_2 0 12 13 14 1 15 16 17 2 18 19 20 3 21 22 23
使用concat来组合数据
在应用中,我们经常需要将不同的数据框组合起来,包括按行合并或按列合并。这时需要使用concat方法,具体应用如下:
按行组合
df3 = pd.concat((df1,df2),'index')
其中index可以写0,二者都可以指定为行合并。合并后结果如下:
col_0 col_1 col_2 0 0 1 2 1 3 4 5 2 6 7 8 3 9 10 11 0 12 13 14 1 15 16 17 2 18 19 20 3 21 22 23
按列组合
按列合并跟安行合并的方法类似,只是后面指定axis为1或columns
df4 = pd.concat((df1,df2),'columns')
合并后结果如下:
col_0 col_1 col_2 col_0 col_1 col_2 0 0 1 2 12 13 14 1 3 4 5 15 16 17 2 6 7 8 18 19 20 3 9 10 11 21 22 23
注意:一般情况下,如果两个dataframe的index不同,会导致合并错误,因此合并前需要保持index相同;如果不同,可以使用df1.index=df2.index先做处理
使用merge来匹配数据
Pandas的merge类似与SQL的多表关联查询,能实现leftjoin、rightjoin、where、innerjoin、fulljoin等操作。
为了模拟实际关联查询时index通常都是不匹配的情况,我们对两个数据框都分别新增一个列主键,用于匹配。
df1['key'] = [1,3,2,4] # 设置df1的主键 df2['key'] = [2,1,4,3] # 设置df2的主键 print(df1) print(df2)
新增主键后两个数据框的数据:
col_0 col_1 col_2 key 0 0 1 2 1 1 3 4 5 3 2 6 7 8 2 3 9 10 11 4 col_0 col_1 col_2 key 0 12 13 14 2 1 15 16 17 1 2 18 19 20 4 3 21 22 23 3
下面我们开始匹配:
df5 = pd.merge(df1,df2,on='key',how='inner')
其中:
- df1和df2为两个要关联的数据框
- on是关联的主键,由于两个数据框有相同的主键命名,因此可以直接用on设置。如果不是,需要单独使用left_on=name1,right_on=name2设置
- how是设置关联的方式,可选值为'left', 'right', 'outer', 'inner',默认值是'inner'
上述代码执行后,我们print输出查看下结果:
print(df5) col_0_x col_1_x col_2_x key col_0_y col_1_y col_2_y 0 0 1 2 1 15 16 17 1 3 4 5 3 21 22 23 2 6 7 8 2 12 13 14 3 9 10 11 4 18 19 20
为了方便,上述方法也可以写为:
df5 = df6.merge(df2,on='key',how='inner')
二者是等效的。
6.5 数据离散化
数据离散化,常用的方法是cut和qcut。二者的应用方法相似,以cut为例,具体应用如下:
df = pd.DataFrame({'mount': np.random.randint(1,100,100)}) # 生成一个100行1列的数据框 df['cut1'] = pd.cut(df['mount'], 4, labels=['bad', 'medium', 'good', 'awesome']) # 为每个分区加标签 df['cut2'] = pd.cut(df['mount'], 4) # 使用默认的区间 print(df.head(5)) # 输出前5条
上述代码中:
- df['mount']要分区/离散化的列
- 4是要分区的数量
- labels是是每个分区的标签,个数需要跟分区数量相同
输出结果如下:
mount cut1 cut2 0 69 good (48.5, 72.25] 1 82 awesome (72.25, 96.0] 2 82 awesome (72.25, 96.0] 3 17 bad (0.905, 24.75] 4 9 bad (0.905, 24.75]
其中,cut2每行对应的区间左侧是区间开始值(不包含),右侧是区间结束值(包含)。分区的标准是默认的4分位数方法。如果要自定义分区边界,则可以这样处理。
bins = [1,20,60,100] # 自定义边界 df['cut3'] = pd.cut(df['mount'], bins) # 切分 print(df.head(5))
处理后的结果如下:
mount cut1 cut2 cut3 0 69 good (48.5, 72.25] (60, 100] 1 82 awesome (72.25, 96.0] (60, 100] 2 82 awesome (72.25, 96.0] (60, 100] 3 17 bad (0.905, 24.75] (1, 20] 4 9 bad (0.905, 24.75] (1, 20]
6.6 改变数据形状
数据框形状的改变在基于单条数据处理后再做合并或建模非常重要,方法是reshape。
df7 = df['mount'] # 建立一个可变对象 df8 = df7.values.reshape((25,4)) # 改为25*4的矩阵 df9 = df7.values.reshape((-1,1)) # 改为100*1的矩阵 df10 = df7.values.reshape((1,-1)) # 改为1*100的矩阵 print(df8.shape) print(df9.shape) print(df10.shape)
上述代码执行后的输出如下:
(25L, 4L) (100L, 1L) (1L, 100L)
提示:对于单行数据的形状reshape,直接使用(-1,1)或(1,-1)来建立一列或一行的shape。
6.7 丢弃数据
Pandas使用drop方法丢弃数据,常用于丢弃特定行或特定列。dropna数据在上面已经介绍,这里介绍对整行或整列数据做丢弃处理。
print(df.shape) # 查看原始数据形状 new_df = df.drop(['cut1'],'columns') # 丢弃cut1,设置为1或columns print(new_df.shape)#查看丢弃一列后的形状 print(new_df.head(3)) #打印输出 new_df2 = df.drop(0,0) # 丢弃第一条数据,设置为0或index print(new_df2.shape)#查看丢弃一行后的形状 print(new_df2.head(3)) #打印输出
上面代码执行后结果如下:
(100, 4) # 原始数据形状 (100, 3) # 丢弃一列后的形状 # 详细数据前3条 mount cut2 cut3 0 69 (48.5, 72.25] (60, 100] 1 82 (72.25, 96.0] (60, 100] 2 82 (72.25, 96.0] (60, 100] (99, 4)# 丢弃一条数据后的形状 # 前3条数据 mount cut1 cut2 cut3 1 82 awesome (72.25, 96.0] (60, 100] 2 82 awesome (72.25, 96.0] (60, 100] 3 17 bad (0.905, 24.75] (1, 20]
6.8 改变数据列的类型
本小节开始的数据框df,其中num默认为int64格式
df.dtypes# 查看数据列类型 # 输出结果 level object num int64 sex object dtype: object
通过astype可以更改为其他格式,例如字符串,方法为:
df['num']= df['num'].astype(np.str) df.dtypes# 查看数据列类型 # 输出结果 level object num object sex object dtype: object
7、数据框的输出
Pandas支持将数据框输出为各种目标格式,例如csv、json、excel等,这些方法都非常简单。以下是输出格式的截图:
以输出csv为例,直接使用:
df.to_csv('my_file.csv')
当然,如果读者感兴趣,可以对index、columns、分隔符等细节做更多设置。
====================【好书推荐,我为自己代盐】====================
《Python数据分析与数据化运营》上市啦!
50+数据流工作知识点
14个数据分析与挖掘主题
8个综合性运营分析案例
涵盖会员、商品、流量、内容4大主题
360°把脉运营问题并贴合数据场景落地
本书主要基于Python实现,其中主要用到的计算库是numpy、pandas和sklearn,其他相关库还包括:
- 标准库:re、time、datetime、json、 base64、os、sys、cPickle、tarfile
- 统计分析:Statsmodels
- 中文处理:结巴分词
- 文本挖掘:Gensim
- 爬虫和解析:requests、Beautiful Soup、xml
- 图像处理:OpenCV和PIL
- 数据读取:xlrd、pymongo、mysql.connector
- 数据预处理:imblearn
- 展示美化类:Matplotlib、graphviz、prettytable、wordcloud、mpl_toolkits、pydotplus
如果你对以下内容感兴趣,那么本书将值得一看:
- KMeans聚类的自动K均值的确立方法
- 基于软方法的多分类模型组合评估模型的应用
- 基于自动下探(下钻、细分)的应用
- 基于增量学习的多项式贝叶斯分类
- pipeline管道技术的应用
- 基于超参数的自动参数值的优化方法
- 特征自动选择
- 文本分类、文本主题挖掘
- 基于自动时间序列ARIMA的P、D、Q的调整
- python决策树规则输出
- 基于自定义图像的文本标签云
- 非结构化数据,例如图像、音频、文本等处理
- 对象持久化处理
有关这本书的写作感受、详细内容介绍、附件(含数据和代码源文件-源代码可更改数据源直接使用)下载、关键知识和方法以及完整书稿目录,请访问 《Python数据分析与数据化运营》新书上线 ,要购买此书请直接点击图片或扫描二维码去京东购买
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- Python数据处理(二):处理 Excel 数据
- 自然语言处理之数据预处理
- Python数据处理(一):处理 JSON、XML、CSV 三种格式数据
- ignite系列数据处理
- R|数据处理|因子型数据
- Python数据处理笔记(1)
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
垃圾回收的算法与实现
中村成洋、相川光 / 丁灵 / 人民邮电出版社 / 2016-7-1 / 99.00元
★ Ruby之父Matz作推荐语:上古传承的魔法,彻底揭开垃圾回收的秘密! ★ 日本天才程序员兼Lisp黑客竹内郁雄审校 本书前半介绍基本GC算法,包括标记-清除GC、引用计数、复制算法的GC、串行GC的算法、并发GC的算法等。后半介绍V8、Rubinius、Dalvik、CPython等几种具体GC的实现。本书适合各领域程序员阅读。一起来看看 《垃圾回收的算法与实现》 这本书的介绍吧!