Python|利用Python进行数据预处理

数据导入到python环境:http://pandas.pydata.org/pandas-docs/stable/io.html(英文版)
IO Tools (Text, CSV, HDF5, ...) The pandas I/O API is a set of top level reader functions accessed like pd.read_csv() that generally return a pandasobject.

  • read_csv
  • read_excel
  • read_hdf
  • read_sql
  • read_json
  • read_msgpack (experimental)
  • read_html
  • read_gbq (experimental)
  • read_stata
  • read_sas
  • read_clipboard
  • read_pickle
The corresponding writer functions are object methods that are accessed like df.to_csv()
  • to_csv
  • to_excel
  • to_hdf
  • to_sql
  • to_json
  • to_msgpack (experimental)
  • to_html
  • to_gbq (experimental)
  • to_stata
  • to_clipboard
  • to_pickle
Here is an informal performance comparison for some of these IO methods.
Note

For examples that use the StringIO class, make sure you import it according to your Python version, i.e.from StringIO import StringIO for Python 2 and from io import StringIO for Python 3.
中文版read_csv参数详解:
pandas.read_csv参数详解
pandas.read_csv参数整理

读取CSV(逗号分割)文件到DataFrame
也支持文件的部分导入和选择迭代
更多帮助参见:http://pandas.pydata.org/pandas-docs/stable/io.html
参数:
filepath_or_buffer : str,pathlib。str, pathlib.Path, py._path.local.LocalPath or any object with a read() method (such as a file handle or StringIO)
可以是URL,可用URL类型包括:http, ftp, s3和文件。对于多文件正在准备中
本地文件读取实例:://localhost/path/to/table.csv

sep : str, default ‘,’
指定分隔符。如果不指定参数,则会尝试使用逗号分隔。分隔符长于一个字符并且不是‘\s+’,将使用python的语法分析器。并且忽略数据中的逗号。正则表达式例子:'\r\t'

delimiter : str, default None
定界符,备选分隔符(如果指定该参数,则sep参数失效)

delim_whitespace : boolean, default False.
指定空格(例如’ ‘或者’ ‘)是否作为分隔符使用,等效于设定sep='\s+'。如果这个参数设定为Ture那么delimiter 参数失效。
在新版本0.18.1支持

header : int or list of ints, default ‘infer’
指定行数用来作为列名,数据开始行数。如果文件中没有列名,则默认为0,否则设置为None。如果明确设定header=0 就会替换掉原来存在列名。header参数可以是一个list例如:[0,1,3],这个list表示将文件中的这些行作为列标题(意味着每一列有多个标题),介于中间的行将被忽略掉(例如本例中的2;本例中的数据1,2,4行将被作为多级标题出现,第3行数据将被丢弃,dataframe的数据从第5行开始。)。
注意:如果skip_blank_lines=True 那么header参数忽略注释行和空行,所以header=0表示第一行数据而不是文件的第一行。

names : array-like, default None
用于结果的列名列表,如果数据文件中没有列标题行,就需要执行header=None。默认列表中不能出现重复,除非设定参数mangle_dupe_cols=True。

index_col : int or sequence or False, default None
用作行索引的列编号或者列名,如果给定一个序列则有多个行索引。
如果文件不规则,行尾有分隔符,则可以设定index_col=False 来是的pandas不适用第一列作为行索引。

usecols : array-like, default None
返回一个数据子集,该列表中的值必须可以对应到文件中的位置(数字可以对应到指定的列)或者是字符传为文件中的列名。例如:usecols有效参数可能是 [0,1,2]或者是 [‘foo’, ‘bar’, ‘baz’]。使用这个参数可以加快加载速度并降低内存消耗。

as_recarray : boolean, default False
不赞成使用:该参数会在未来版本移除。请使用pd.read_csv(...).to_records()替代。
返回一个Numpy的recarray来替代DataFrame。如果该参数设定为True。将会优先squeeze参数使用。并且行索引将不再可用,索引列也将被忽略。

squeeze : boolean, default False
如果文件值包含一列,则返回一个Series

prefix : str, default None
在没有列标题时,给列添加前缀。例如:添加‘X’ 成为 X0, X1, ...

mangle_dupe_cols : boolean, default True
重复的列,将‘X’...’X’表示为‘X.0’...’X.N’。如果设定为false则会将所有重名列覆盖。

dtype : Type name or dict of column -> type, default None
每列数据的数据类型。例如 {‘a’: np.float64, ‘b’: np.int32}

engine : {‘c’, ‘python’}, optional
Parser engine to use. The C engine is faster while the python engine is currently more feature-complete.
使用的分析引擎。可以选择C或者是python。C引擎快但是Python引擎功能更加完备。

converters : dict, default None
列转换函数的字典。key可以是列名或者列的序号。

true_values : list, default None
Values to consider as True

false_values : list, default None
Values to consider as False

skipinitialspace : boolean, default False
忽略分隔符后的空白(默认为False,即不忽略).

skiprows : list-like or integer, default None
需要忽略的行数(从文件开始处算起),或需要跳过的行号列表(从0开始)。

skipfooter : int, default 0
从文件尾部开始忽略。 (c引擎不支持)

skip_footer : int, default 0
不推荐使用:建议使用skipfooter ,功能一样。

nrows : int, default None
需要读取的行数(从文件头开始算起)。

na_values : scalar, str, list-like, or dict, default None
一组用于替换NA/NaN的值。如果传参,需要制定特定列的空值。默认为‘1.#IND’, ‘1.#QNAN’, ‘N/A’, ‘NA’, ‘NULL’, ‘NaN’, ‘nan’`.

keep_default_na : bool, default True
如果指定na_values参数,并且keep_default_na=False,那么默认的NaN将被覆盖,否则添加。

na_filter : boolean, default True
是否检查丢失值(空字符串或者是空值)。对于大文件来说数据集中没有空值,设定na_filter=False可以提升读取速度。

verbose : boolean, default False
是否打印各种解析器的输出信息,例如:“非数值列中缺失值的数量”等。

skip_blank_lines : boolean, default True
如果为True,则跳过空行;否则记为NaN。

parse_dates : boolean or list of ints or names or list of lists or dict, default False
  • boolean. True -> 解析索引
  • list of ints or names. e.g. If [1, 2, 3] -> 解析1,2,3列的值作为独立的日期列;
  • list of lists. e.g. If [[1, 3]] -> 合并1,3列作为一个日期列使用
  • dict, e.g. {‘foo’ : [1, 3]} -> 将1,3列合并,并给合并后的列起名为"foo"

infer_datetime_format : boolean, default False
如果设定为True并且parse_dates 可用,那么pandas将尝试转换为日期类型,如果可以转换,转换方法并解析。在某些情况下会快5~10倍。

keep_date_col : boolean, default False
如果连接多列解析日期,则保持参与连接的列。默认为False。
【Python|利用Python进行数据预处理】
date_parser : function, default None
用于解析日期的函数,默认使用dateutil.parser.parser来做转换。Pandas尝试使用三种不同的方式解析,如果遇到问题则使用下一种方式。
1.使用一个或者多个arrays(由parse_dates指定)作为参数;
2.连接指定多列字符串作为一个列作为参数;
3.每行调用一次date_parser函数来解析一个或者多个字符串(由parse_dates指定)作为参数。

dayfirst : boolean, default False
DD/MM格式的日期类型

iterator : boolean, default False
返回一个TextFileReader 对象,以便逐块处理文件。

chunksize : int, default None
文件块的大小, See IO Tools docs for more informationon iterator and chunksize.

compression : {‘infer’, ‘gzip’, ‘bz2’, ‘zip’, ‘xz’, None}, default ‘infer’
直接使用磁盘上的压缩文件。如果使用infer参数,则使用 gzip, bz2, zip或者解压文件名中以‘.gz’, ‘.bz2’, ‘.zip’, or ‘xz’这些为后缀的文件,否则不解压。如果使用zip,那么ZIP包中国必须只包含一个文件。设置为None则不解压。
新版本0.18.1版本支持zip和xz解压

thousands : str, default None
千分位分割符,如“,”或者“."

decimal : str, default ‘.’
字符中的小数点 (例如:欧洲数据使用’,‘).

float_precision : string, default None
Specifies which converter the C engine should use for floating-point values. The options are None for the ordinary converter, high for the high-precision converter, and round_trip for the round-trip converter.
指定

lineterminator : str (length 1), default None
行分割符,只在C解析器下使用。

quotechar : str (length 1), optional
引号,用作标识开始和解释的字符,引号内的分割符将被忽略。

quoting : int or csv.QUOTE_* instance, default 0
控制csv中的引号常量。可选 QUOTE_MINIMAL (0), QUOTE_ALL (1), QUOTE_NONNUMERIC (2) or QUOTE_NONE (3)

doublequote : boolean, default True
双引号,当单引号已经被定义,并且quoting 参数不是QUOTE_NONE的时候,使用双引号表示引号内的元素作为一个元素使用。

escapechar : str (length 1), default None
当quoting 为QUOTE_NONE时,指定一个字符使的不受分隔符限值。

comment : str, default None
标识着多余的行不被解析。如果该字符出现在行首,这一行将被全部忽略。这个参数只能是一个字符,空行(就像skip_blank_lines=True)注释行被header和skiprows忽略一样。例如如果指定comment='#' 解析‘#empty\na,b,c\n1,2,3’ 以header=0 那么返回结果将是以’a,b,c'作为header。

encoding : str, default None
指定字符集类型,通常指定为'utf-8'. List of Python standard encodings

dialect : str or csv.Dialect instance, default None
如果没有指定特定的语言,如果sep大于一个字符则忽略。具体查看csv.Dialect 文档

tupleize_cols : boolean, default False
Leave a list of tuples on columns as is (default is to convert to a Multi Index on the columns)

error_bad_lines : boolean, default True
如果一行包含太多的列,那么默认不会返回DataFrame ,如果设置成false,那么会将改行剔除(只能在C解析器下使用)。

warn_bad_lines : boolean, default True
如果error_bad_lines =False,并且warn_bad_lines =True 那么所有的“bad lines”将会被输出(只能在C解析器下使用)。

low_memory : boolean, default True
分块加载到内存,再低内存消耗中解析。但是可能出现类型混淆。确保类型不被混淆需要设置为False。或者使用dtype 参数指定类型。注意使用chunksize 或者iterator 参数分块读入会将整个文件读入到一个Dataframe,而忽略类型(只能在C解析器中有效)

buffer_lines : int, default None
不推荐使用,这个参数将会在未来版本移除,因为他的值在解析器中不推荐使用

compact_ints : boolean, default False
不推荐使用,这个参数将会在未来版本移除
如果设置compact_ints=True ,那么任何有整数类型构成的列将被按照最小的整数类型存储,是否有符号将取决于use_unsigned 参数

use_unsigned : boolean, default False
不推荐使用:这个参数将会在未来版本移除
如果整数列被压缩(i.e. compact_ints=True),指定被压缩的列是有符号还是无符号的。
memory_map : boolean, default False
如果使用的文件在内存内,那么直接map文件使用。使用这种方式可以避免文件再次进行IO操作。


数据预处理过程:http://www.kuqin.com/shuoit/20160206/350580.html
导语
Python正迅速成为数据科学家偏爱的语言,这合情合理。它拥有作为一种编程语言广阔的生态环境以及众多优秀的科学计算库。如果你刚开始学习Python,可以先了解一下Python的学习路线。
在众多的科学计算库中,我认为Pandas对数据科学运算最有用。Pandas,加上Scikit-learn几乎能构成了数据科学家所需的全部工具。本文旨在提供Python数据处理的12种方法。文中也分享了一些会让你的工作更加便捷的小技巧。
在继续推进之前,我推荐读者阅览一些关于数据探索 (data exploration)的代码。
为了帮助理解,本文用一个具体的数据集进行运算和操作。本文使用了贷款预测(loan prediction) 问题数据集,下载数据集请到http://datahack.analyticsvidhya.com/contest/practice-problem-loan-prediction。
开始工作
首先我要导入要用的模块,并把数据集载入Python环境。
import pandas as pdimport numpy as npdata = https://www.it610.com/article/pd.read_csv("train.csv", index_col="Loan_ID")

1.布尔索引(Boolean Indexing)
如何你想用基于某些列的条件筛选另一列的值,你会怎么做?例如,我们想要一个全部无大学学历但有贷款的女性列表。这里可以使用布尔索引。代码如下:
data.loc[(data["Gender"]=="Female") & (data["Education"]=="Not Graduate") & (data["Loan_Status"]=="Y"), ["Gender","Education","Loan_Status"]]

?
想了解更多请阅读 Pandas Selecting and Indexing
2.Apply函数
Apply是摆弄数据和创造新变量时常用的一个函数。Apply把函数应用于数据框的特定行/列之后返回一些值。这里的函数既可以是系统自带的也可以是用户定义的。例如,此处可以用它来寻找每行每列的缺失值个数:
#创建一个新函数:def num_missing(x):return sum(x.isnull())#Apply到每一列: print "Missing values per column:"print data.apply(num_missing, axis=0) #axis=0代表函数应用于每一列#Apply到每一行:print "nMissing values per row:" print data.apply(num_missing, axis=1).head() #axis=1代表函数应用于每一行

输出结果:

由此我们得到了想要的结果。
注意:第二个输出使用了head()函数,因为数据包含太多行。
想了解更多请阅读 Pandas Reference (apply)
3.替换缺失值
‘fillna()’ 可以一次解决这个问题。它被用来把缺失值替换为所在列的平均值/众数/中位数。
#首先导入一个寻找众数的函数:from scipy.stats import modemode(data['Gender'])

输出: ModeResult(mode=array([‘Male’], dtype=object), count=array([489]))
返回了众数及其出现次数。记住,众数可以是个数组,因为高频的值可能不只一个。我们通常默认使用第一个:
mode(data['Gender']).mode[0]


现在可以填补缺失值,并用上一步的技巧来检验。
#值替换:data['Gender'].fillna(mode(data['Gender']).mode[0], inplace=True)data['Married'].fillna(mode(data['Married']).mode[0], inplace=True) data['Self_Employed'].fillna(mode(data['Self_Employed']).mode[0], inplace=True)#再次检查缺失值以确认:print data.apply(num_missing, axis=0)


由此可见,缺失值确定被替换了。请注意这是最基本的替换方式,其他更复杂的技术,如为缺失值建模、用分组平均数(平均值/众数/中位数)填充,会在今后的文章提到。
想了解更多请阅读 Pandas Reference (fillna)
4.透视表
Pandas可以用来创建 Excel式的透视表。例如,“LoanAmount”这个重要的列有缺失值。我们可以用根据 ‘Gender’、‘Married’、‘Self_Employed’分组后的各组的均值来替换缺失值。每个组的 ‘LoanAmount’可以用如下方法确定:
#Determine pivot tableimpute_grps = data.pivot_table(values=["LoanAmount"], index=["Gender","Married","Self_Employed"], aggfunc=np.mean)print impute_grps


想了解更多请阅读 Pandas Reference (Pivot Table)
5.多重索引
你可能注意到上一步骤的输出有个奇怪的性质。每个索引都是由三个值组合而成。这叫做多重索引。它可以帮助运算快速进行。
延续上面的例子,现在我们有了每个分组的值,但还没有替换。这个任务可以用现在学过的多个技巧共同完成。
#只在带有缺失值的行中迭代:for i,row in data.loc[data['LoanAmount'].isnull(),:].iterrows():ind = tuple([row['Gender'],row['Married'],row['Self_Employed']]) data.loc[i,'LoanAmount'] = impute_grps.loc[ind].values[0]#再次检查缺失值以确认: print data.apply(num_missing, axis=0)


注:
多重索引需要在loc中用到定义分组group的元组(tuple)。这个元组会在函数中使用。
需要使用.values[0]后缀。因为默认情况下元素返回的顺序与原数据库不匹配。在这种情况下,直接指派会返回错误。
6. 二维表
这个功能可被用来获取关于数据的初始“印象”(观察)。这里我们可以验证一些基本假设。例如,本例中“Credit_History” 被认为对欠款状态有显著影响。可以用下面这个二维表进行验证:
pd.crosstab(data["Credit_History"],data["Loan_Status"],margins=True)


这些数字是绝对数值。不过,百分比数字更有助于快速了解数据。我们可以用apply函数达到目的:
def percConvert(ser):return ser/float(ser[-1]) pd.crosstab(data["Credit_History"],data["Loan_Status"],margins=True).apply(percConvert, axis=1)


现在可以很明显地看出,有信用记录的人获得贷款的可能性更高:有信用记录的人有80% 获得了贷款,没有信用记录的人只有 9% 获得了贷款。
但不仅仅是这样,其中还包含着更多信息。由于我现在知道了有信用记录与否非常重要,如果用信用记录来预测是否会获得贷款会怎样?令人惊讶的是,在614次试验中我们能预测正确460次,足足有75%!
如果此刻你在纳闷,我们要统计模型有什么用,我不会怪你。但相信我,在此基础上提高0.001%的准确率都是充满挑战性的。你是否愿意接受这个挑战?
注:对训练集而言是75% 。在测试集上有些不同,但结果相近。同时,我希望这个例子能让人明白,为什么提高0.05% 的正确率就能在Kaggle排行榜上跳升500个名次。
想了解更多请阅读Pandas Reference (crosstab)
用 Python 做数据处理必看:12 个使效率倍增的 Pandas 技巧(上)《用 Python 做数据处理必看:12 个使效率倍增的 Pandas 技巧》
7 – 数据框合并
当我们有收集自不同来源的数据时,合并数据框就变得至关重要。假设对于不同的房产类型,我们有不同的房屋均价数据。让我们定义这样一个数据框:
prop_rates = pd.DataFrame([1000, 5000, 12000], index=['Rural','Semiurban','Urban'],columns=['rates'])prop_rates


现在可以把它与原始数据框合并:
data_merged = data.merge(right=prop_rates, how='inner',left_on='Property_Area',right_index=True, sort=False) data_merged.pivot_table(values='Credit_History',index=['Property_Area','rates'], aggfunc=len)


这张透视表验证了合并成功。注意这里的 ‘values’无关紧要,因为我们只是单纯计数。
想了解更多请阅读Pandas Reference (merge)
8 – 给数据框排序
Pandas可以轻松基于多列排序。方法如下:
data_sorted = data.sort_values(['ApplicantIncome','CoapplicantIncome'], ascending=False) data_sorted[['ApplicantIncome','CoapplicantIncome']].head(10)


注:Pandas 的“sort”函数现在已经不推荐使用,我们用 “sort_values”函数代替。
想了解更多请阅读Pandas Reference (sort_values)
9 – 绘图(箱型图&直方图)
许多人可能没意识到Pandas可以直接绘制箱型图和直方图,不必单独调用matplotlib。只需要一行代码。举例来说,如果我们想根据贷款状态Loan_Status来比较申请者收入ApplicantIncome:
data.boxplot(column="ApplicantIncome",by="Loan_Status")


data.hist(column="ApplicantIncome",by="Loan_Status",bins=30)


可以看出获得/未获得贷款的人没有明显的收入差异,即收入不是决定性因素。
想了解更多请阅读Pandas Reference (hist) | Pandas Reference (boxplot)
10 – 用Cut函数分箱
有时把数值聚集在一起更有意义。例如,如果我们要为交通状况(路上的汽车数量)根据时间(分钟数据)建模。具体的分钟可能不重要,而时段如“上午”“下午”“傍晚”“夜间”“深夜”更有利于预测。如此建模更直观,也能避免过度拟合。
这里我们定义一个简单的、可复用的函数,轻松为任意变量分箱。
#分箱:def binning(col, cut_points, labels=None):#Define min and max values:minval = col.min()maxval = col.max() #利用最大值和最小值创建分箱点的列表break_points = [minval] + cut_points + [maxval] #如果没有标签,则使用默认标签0 ... (n-1)if not labels:labels = range(len(cut_points)+1)#使用pandas的cut功能分箱colBin = pd.cut(col,bins=break_points,labels=labels,include_lowest=True) return colBin#为年龄分箱:cut_points = [90,140,190]labels = ["low","medium","high","very high"]data["LoanAmount_Bin"] = binning(data["LoanAmount"], cut_points, labels)print pd.value_counts(data["LoanAmount_Bin"], sort=False)


想了解更多请阅读 Pandas Reference (cut)
11 – 为分类变量编码
有时,我们会面对要改动分类变量的情况。原因可能是:
有些算法(如罗吉斯回归)要求所有输入项目是数字形式。所以分类变量常被编码为0, 1….(n-1)
有时同一个分类变量可能会有两种表现方式。如,温度可能被标记为“High”, “Medium”, “Low”,“H”, “low”。这里 “High” 和 “H”都代表同一类别。同理, “Low” 和“low”也是同一类别。但Python会把它们当作不同的类别。
一些类别的频数非常低,把它们归为一类是个好主意。
这里我们定义了一个函数,以字典的方式输入数值,用‘replace’函数进行编码。
#使用Pandas replace函数定义新函数:def coding(col, codeDict):colCoded = pd.Series(col, copy=True)for key, value in codeDict.items(): colCoded.replace(key, value, inplace=True)return colCoded? #把贷款状态LoanStatus编码为Y=1, N=0:print 'Before Coding:'print pd.value_counts(data["Loan_Status"])data["Loan_Status_Coded"] = coding(data["Loan_Status"], {'N':0,'Y':1})print 'nAfter Coding:' print pd.value_counts(data["Loan_Status_Coded"])


编码前后计数不变,证明编码成功。
想了解更多请阅读 Pandas Reference (replace)
12 – 在一个数据框的各行循环迭代
这不是一个常见的操作。但你总不想卡在这里吧?有时你会需要用一个for循环来处理每行。例如,一个常见的问题是变量处置不当。通常见于以下情况:
带数字的分类变量被当做数值。
(由于出错)带文字的数值变量被当做分类变量。
所以通常来说手动定义变量类型是个好主意。如我们检查各列的数据类型:
#检查当前数据类型:data.dtypes


这里可以看到分类变量Credit_History被当作浮点数。对付这个问题的一个好办法是创建一个包含变量名和类型的csv文件。通过这种方法,我们可以定义一个函数来读取文件,并为每列指派数据类型。举例来说,我们创建了csv文件datatypes.csv。

#载入文件:colTypes = pd.read_csv('datatypes.csv')print colTypes


载入这个文件之后,我们能对每行迭代,把用‘type’列把数据类型指派到‘feature’ 列对应的项目。
#迭代每行,指派变量类型。#注,astype用来指定变量类型。for i, row in colTypes.iterrows(): #i: dataframe索引; row: 连续的每行if row['feature']=="categorical": data[row['feature']]=data[row['feature']].astype(np.object)elif row['feature']=="continuous": data[row['feature']]=data[row['feature']].astype(np.float)print data.dtypes

现在信用记录这一列的类型已经成了‘object’ ,这在Pandas中代表分类变量。
想了解更多请阅读Pandas Reference (iterrows)
结语
本文中我们介绍了多个可以帮助我们减轻数据探索、特征工程工作负担的函数。此外,我们也定义了一些函数,这些函数可以在不同的数据集上复用以获得相同效果。
参考文献:
python数据分析入门——数据导入数据预处理基本操作

    推荐阅读