有下列常见方法
read_csv 从文件、URL、类似文件的对象中读取数据,默认使用逗号为分隔符号
read_table 从文件、URL、类似文件的对象中读取数据,默认使用tab ('\t')为分隔符号
read_fwf 从固定宽度的列格式文件读取数据
其中read_csv方法相关参数及说明
Argument Description
path 文件路径,URL
sep or delimiter 用来分割行的的字符序列或者表达式
header 作为列名称的行号,默认为0(第一行),如果没有列名,需要指明header=None
index_col 作为结果中的行索引的列名称或列序号
skiprows 从文件开始读取时跳过的行序号
na_values 用NA值替换的值
parse_dates 将date数据解析成datetime,默认是False,为True时将解析所有列
keep_date_col 如果将指定列进行日期解析(parse date)删除指定列,默认为True
.................
(1)正常读取。
假若有 如下csv文件(ex1.csv)
a,b,c,d,message
1,2,3,4,hello
5,6,7,8,world
9,10,11,12,foo
使用read_csv方法,由于默认是以逗号为分割符号,所以直接使用。(
注:下列方法等同于:pd.read_table('ch06/ex1.csv', sep=','),假若有多个空格作为分割符号,read_table中的sep='\s+'
In [847]: df = pd.read_csv('ch06/ex1.csv') In [848]: df Out[848]: a b c d message 0 1 2 3 4 hello 1 5 6 7 8 world 2 9 10 11 12 foo
(2)文件中没有指定列名。
如下csv文件(ex2.csv)
1,2,3,4,hello
5,6,7,8,world
9,10,11,12,foo
声明header为空
In [851]: pd.read_csv('ch06/ex2.csv', header=None) Out[851]: X.1 X.2 X.3 X.4 X.5 0 1 2 3 4 hello 1 5 6 7 8 world 2 9 10 11 12 foo
或者指定列名
In [852]: pd.read_csv('ch06/ex2.csv', names=['a', 'b', 'c', 'd', 'message']) Out[852]: a b c d message 0 1 2 3 4 hello 1 5 6 7 8 world 2 9 10 11 12 foo
(3)使用index_col参数
指定 索引列的列名称
In [853]: names = ['a', 'b', 'c', 'd', 'message'] In [854]: pd.read_csv('ch06/ex2.csv', names=names, index_col='message') Out[854]: a b c d message hello 1 2 3 4 world 5 6 7 8 foo 9 10 11 12
还可以通过传给多列指定相同前缀,来构造层次索引,只需要传入 列编号或列名称即可
In [855]: !cat ch06/csv_mindex.csv key1,key2,value1,value2 one,a,1,2 one,b,3,4 one,c,5,6 one,d,7,8 two,a,9,10 two,b,11,12 two,c,13,14 two,d,15,16
In [856]: parsed = pd.read_csv('ch06/csv_mindex.csv', index_col=['key1', 'key2']) In [857]: parsed Out[857]: value1 value2 key1 key2 one a 1 2 b 3 4 c 5 6 d 7 8 two a 9 10 b 11 12 c 13 14 d 15 16
(4)有选择的读取和 有选择的使用空值替换
假若我们有如下数据:
In [861]: !cat ch06/ex4.csv # hey! a,b,c,d,message # just wanted to make things more difficult for you # who reads CSV files with computers, anyway? 1,2,3,4,hello 5,6,7,8,world 9,10,11,12,foo
跳过其中的指定行,使用参数skiprows
In [862]: pd.read_csv('ch06/ex4.csv', skiprows=[0, 2, 3]) Out[862]: a b c d message 0 1 2 3 4 hello 1 5 6 7 8 world 2 9 10 11 12 foo
假若有数据如下(第3行5列缺失,2行5列为NaN):
In [863]: !cat ch06/ex5.csv something,a,b,c,d,message o ne,1,2,3,4,NA two,5,6,,8,world three,9,10,11,12,foo
使用dict类型数据中行列信息指定用空值替换某些记录,使用参数na_values
In [869]: sentinels = {'message': ['foo', 'NA'], 'something': ['two']} In [870]: pd.read_csv('ch06/ex5.csv', na_values=sentinels) Out[870]: something a b c d message 0 one 1 2 3 4 NaN 1 NaN 5 6 NaN 8 world 2 three 9 10 11 12 NaN
(5)分片段读取文本
只读取前几行,使用参数nrow
In [873]: pd.read_csv('ch06/ex6.csv', nrows=5) Out[873]: one two three four key 0 0.467976 -0.038649 -0.295344 -1.824726 L 1 -0.358893 1.404453 0.704965 -0.200638 B 2 -0.501840 0.659254 -0.421691 -0.057688 G 3 0.204886 1.074134 1.388361 -0.982404 R 4 0.354628 -0.133116 0.283763 -0.837063 Q
使用chunksize来指定读取的行数,注意一个chunksize,返回的是可以迭代的数据对象
chunker = pd.read_csv('ch06/ex6.csv', chunksize=1000) tot = Series([])
迭代读取根据属性chunksize指定的文件片段。下列代码是统计文件 ex6.csv前1000行中,”key“列不同值的数量
for piece in chunker: tot = tot.add(piece['key'].value_counts(), fill_value=0) tot = tot.order(ascending=False) In [877]: tot[:10] Out[877]: E 368 X 364 L 346 O 343 Q 340 M 338 J 337 F 335 K 334 H 330
写出文件使用的是 to_csv方法,方法默认使用逗号作为分隔符,可以通过参数 sep修改。默认第一行作为列名,第一列作为行名,可以分别通过参数index=False,header=False修改。
有如下文件:
In [878]: data = pd.read_csv('ch06/ex5.csv') In [879]: data Out[879]: something a b c d message 0 one 1 2 3 4 NaN 1 two 5 6 NaN 8 world 2 three 9 10 11 12 foo
如果使用参数sys.stdout,代表直接打印
In [882]: data.to_csv(sys.stdout, sep='|') |something|a|b|c|d|message 0|one|1|2|3.0|4| 1|two|5|6||8|world 2|three|9|10|11.0|12|foo
3 处理XML、HTML文件
python有多个包可以用来处理XML和HTML文件,其中 lxml 包最为强大。先使用lxml.html来接受HTML文件,再使用lxml.objectify来解析。
下述代码获取的是雅虎金融股票数据:
from lxml.html import parse from urllib2 import urlopen parsed = parse(urlopen('http://finance.yahoo.com/q/op?s=AAPL+Options')) doc = parsed.getroot()
通过以上 doc对象,我们可以抽取任何HTML文件标签内容,使用findall方法。下面的代码用来获取标签<a>(即超链接)的位置
In [906]: links = doc.findall('.//a') In [907]: links[15:20] Out[907]: [<Element a at 0x6c488f0>, <Element a at 0x6c48950>, <Element a at 0x6c489b0>, <Element a at 0x6c48a10>, <Element a at 0x6c48a70>]
以上对象只是HTML元素,想进一步获得URL和链接文本,需要使用get方法,如果想获得URL中呈现文本,需要使用text_content方法
In [908]: lnk = links[28] In [909]: lnk Out[909]: <Element a at 0x6c48dd0> In [910]: lnk.get('href') Out[910]: 'http://biz.yahoo.com/special.html' In [911]: lnk.text_content() Out[911]: 'Special Editions'
使用 lxml.objectify来解析XML文件。
一下文件是 纽约地铁交通运输署的一份关于地铁和公交运输服务的说明书。一下是部分数据示例:
<INDICATOR> <INDICATOR_SEQ>373889</INDICATOR_SEQ> <PARENT_SEQ></PARENT_SEQ> <AGENCY_NAME>Metro-North Railroad</AGENCY_NAME> <INDICATOR_NAME>Escalator Availability</INDICATOR_NAME> <DESCRIPTION>Percent of the time that escalators are operational systemwide. The availability rate is based on physical observations performed the morning of regular business days only. This is a new indicator the agency began reporting in 2009. </DESCRIPTION> <PERIOD_YEAR>2011</PERIOD_YEAR> <PERIOD_MONTH>12</PERIOD_MONTH> <CATEGORY>Service Indicators</CATEGORY> <FREQUENCY>M</FREQUENCY> <DESIRED_CHANGE>U</DESIRED_CHANGE> <INDICATOR_UNIT>%</INDICATOR_UNIT> <DECIMAL_PLACES>1</DECIMAL_PLACES> <YTD_TARGET>97.00</YTD_TARGET> <YTD_ACTUAL></YTD_ACTUAL> <MONTHLY_TARGET>97.00</MONTHLY_TARGET> <MONTHLY_ACTUAL></MONTHLY_ACTUAL> </INDICATOR>
使用 lxml.objectify的getroot方法将得到XML文件的根节点
from lxml import objectify path = 'Performance_MNR.xml' parsed = objectify.parse(open(path)) root = parsed.getroot()
使用root.INDICATOR可以获得相应XML元素每个INDICATOR记录的迭代器,对每条记录,可以通过字典数据类型来选择性排除部分不需要的标签。
data = [] skip_fields = ['PARENT_SEQ', 'INDICATOR_SEQ', 'DESIRED_CHANGE', 'DECIMAL_PLACES'] #排除的元素标签 for elt in root.INDICATOR: el_data = {} for child in elt.getchildren(): if child.tag in skip_fields: continue el_data[child.tag] = child.pyval data.append(el_data)
xls_file = pd.ExcelFile('data.xls') table = xls_file.parse('Sheet1')