au加载默认的输入和输出设备失败_《利用Python进行数据分析》六章·数据加载、存储与文件格式·学习笔记(一)...

ef81b189127aa868fe145992b4c0cb42.png

一、数据加载、存储与文件格式

访问数据是使用工具的第一步,着重介绍pandas的数据输入与输出。

输入输出通常可以划分为几个大类:读取文本文件和其他更高效的磁盘存储格式,加载数据库中的数据,利用Web API操作网络资源。

二、实例

2.1 读写文本格式的数据

pandas提供了一些用于将表格型数据读取为DataFrame对象的函数。

·read_ csv

从文件、URL、文件型对象中加载带分隔符的数据。默认分隔符为逗号

·read_ table

从文件、URL、文件型对象中加载带分隔符的数据。默认分隔符为制表符(t)

接着介绍一下这些函数在将文本数据转换为DataFrame时所用到的一些技术。这些函数的选项可以划分为以下几个大类:

· 索引:将一个或多个列当做返回的DataFrame处理,以及是否从文件、用户获取列名。

· 类型推断和数据转换:包括用户定义值的转换、和自定义的缺失值标记列表等。

· 日期解析:包括组合功能,比如将分散在多个列中的日期时间信息组合成结果中的单个列。

· 迭代:支持对大文件进行逐块迭代。

· 不规整数据问题:跳过一些行、页脚、注释或其他一些不重要的东西(比如由成千上万个逗号隔开的数值数据)。

因为工作中实际碰到的数据可能十分混乱,一些数据加载函数(尤其是read_csv)的选项逐渐变得复杂起来(read_csv有超过50个参数)。pandas文档有这些参数的例子,如果你感到阅读某个文件很难,可以通过相似的足够多的例子找到正确的参数。

其中一些函数,比如pandas.read_csv,有类型推断功能,因为列数据的类型不属于数据类型。也就是说,你不需要指定列的类型到底是数值、整数、布尔值,还是字符串。其它的数据格式,如HDF5、Feather和msgpack,会在格式中存储数据类型。

日期和其他自定义类型的处理需要多花点工夫才行。首先我们来看一个以逗号分隔的CSV文本文件(案例用文件下载地址:https://github.com/wesm/pydata-book):

type examplesex1.csv#windowsx系统下cmd,记得斜杠是向右下

a,b,c,d,message1,2,3,4,hello5,6,7,8,world9,10,11,12,foo

由于该文件以逗号分隔,所以我们可以使用read_csv将其读入一个DataFrame:

In [9]: df = pd.read_csv('examples/ex1.csv')

In [10]: df

Out[10]:

a b c d message

0 1 2 3 4 hello

1 5 6 7 8 world

2 9 10 11 12 foo

我们还可以使用read_table,并指定分隔符:

In [11]: pd.read_table('examples/ex1.csv', sep=',')

Out[11]:

a b c d message

0 1 2 3 4 hello

1 5 6 7 8 world

2 9 10 11 12 foo

并不是所有文件都有标题行。看看下面这个文件:

type examplesex2.csv

1,2,3,4,hello

5,6,7,8,world

9,10,11,12,foo

读入该文件的办法有两个。你可以让pandas为其分配默认的列名,也可以自己定义列名:

In [13]: pd.read_csv('examples/ex2.csv', header=None)

Out[13]:

0 1 2 3 4

0 1 2 3 4 hello

1 5 6 7 8 world

2 9 10 11 12 foo

In [14]: pd.read_csv('examples/ex2.csv', names=['a', 'b', 'c', 'd', 'message'])#命名

Out[14]:

a b c d message

0 1 2 3 4 hello

1 5 6 7 8 world

2 9 10 11 12 foo

假设你希望将message列做成DataFrame的索引。你可以明确表示要将该列放到索引4的位置上,也可以通过index_col参数指定"message":

In [15]: names = ['a', 'b', 'c', 'd', 'message']

In [16]: pd.read_csv('examples/ex2.csv', names=names, index_col='message')

Out[16]:

a b c d

message

hello 1 2 3 4

world 5 6 7 8

foo 9 10 11 12

如果希望将多个列做成一个层次化索引,只需传入由列编号或列名组成的列表即可:

CMD: type examplescsv_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 [18]: parsed = pd.read_csv('examples/csv_mindex.csv',

....: index_col=['key1', 'key2'])#层次化索引

In [19]: parsed

Out[19]:

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

有些情况下,有些表格可能不是用固定的分隔符去分隔字段的(比如空白符或其它模式)。看看下面这个文本文件:

In [20]: list(open('examples/ex3.txt'))

Out[20]:

[' A B Cn',

'aaa -0.264438 -1.026059 -0.619500n',

'bbb 0.927272 0.302904 -0.032399n',

'ccc -0.264273 -0.386314 -0.217601n',

'ddd -0.871858 -0.348382 1.100491n']

虽然可以手动对数据进行规整,这里的字段是被数量不同的空白字符间隔开的。这种情况下,你可以传递一个正则表达式作为read_table的分隔符。可以用正则表达式表达为s+,于是有:

In [21]: result = pd.read_table('examples/ex3.txt', sep='s+')#s匹配任何空白字符,+表示至少一个字符

In [22]: result

Out[22]:

A B C

aaa -0.264438 -1.026059 -0.619500

bbb 0.927272 0.302904 -0.032399

ccc -0.264273 -0.386314 -0.217601

ddd -0.871858 -0.348382 1.100491

这里,由于列名比数据行的数量少,所以read_table推断第一列应该是DataFrame的索引。

这些解析器函数还有许多参数可以帮助你处理各种各样的异形文件格式。例如可以用skiprows跳过文件的第一行、第三行和第四行:

CMD:type examplesex4.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

In [24]: pd.read_csv('examples/ex4.csv', skiprows=[0, 2, 3])

Out[24]:

a b c d message

0 1 2 3 4 hello

1 5 6 7 8 world

2 9 10 11 12 foo

缺失值处理是文件解析任务中的一个重要组成部分。缺失数据经常是要么没有(空字符串),要么用某个标记值表示。默认情况下,pandas会用一组经常出现的标记值进行识别,比如NA及NULL:

CMD:type examplesex5.csv

something,a,b,c,d,message

one,1,2,3,4,NA

two,5,6,,8,world

three,9,10,11,12,foo

In [26]: result = pd.read_csv('examples/ex5.csv')

In [27]: result

Out[27]:

something a b c d message

0 one 1 2 3.0 4 NaN

1 two 5 6 NaN 8 world

2 three 9 10 11.0 12 foo

In [28]: pd.isnull(result)

Out[28]:

something a b c d message

0 False False False False False True

1 False False False True False False

2 False False False False False False

na_values可以用一个列表或集合的字符串表示缺失值:

In [29]: result = pd.read_csv('examples/ex5.csv', na_values=['NULL'])

In [30]: result

Out[30]:

something a b c d message

0 one 1 2 3.0 4 NaN

1 two 5 6 NaN 8 world

2 three 9 10 11.0 12 foo

字典的各列可以使用不同的NA标记值,此处和原数据截图对比一下

In [31]: sentinels = {'message': ['foo', 'NA'], 'something': ['two']}

#末列foo转NaN,一列two转NaN

In [32]: pd.read_csv('examples/ex5.csv', na_values=sentinels)

Out[32]:

something a b c d message

0 one 1 2 3.0 4 NaN

1 NaN 5 6 NaN 8 world

2 three 9 10 11.0 12 NaN

3f62ac8c7a0931498380a715779a67ef.png

2.2逐块读取文本文件

在处理很大的文件时,或找出大文件中的参数集以便于后续处理时,你可能只想读取文件的一小部分或逐块对文件进行迭代。

在看大文件之前,我们先设置pandas显示地更紧些:

In [33]: pd.options.display.max_rows = 10

然后有:

In [34]: result = pd.read_csv('examples/ex6.csv')

In [35]: result

Out[35]:

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

... ... ... ... ... ..

9995 2.311896 -0.417070 -1.409599 -0.515821 L

9996 -0.479893 -0.650419 0.745152 -0.646038 E

9997 0.523331 0.787112 0.486066 1.093156 K

9998 -0.362559 0.598894 -1.843201 0.887292 G

9999 -0.096376 -1.012999 -0.657431 -0.573315 0

[10000 rows x 5 columns]

如果只想读取几行(避免读取整个文件),通过nrows进行指定即可:

In [36]: pd.read_csv('examples/ex6.csv', nrows=5)

Out[36]:

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(行数):

In [874]: chunker = pd.read_csv('examples/ex6.csv', chunksize=1000)

In [875]: chunker

Out[875]: <pandas.io.parsers.TextParser at 0x8398150>

read_csv所返回的这个TextParser对象使你可以根据chunksize对文件进行逐块迭代。比如说,我们可以迭代处理ex6.csv,将值计数聚合到"key"列中,如下所示:

tot = pd.Series([])

for piece in chunker:

tot = tot.add(piece['key'].value_counts(), fill_value=0)

tot = tot.sort_values(ascending=False)

然后有:

In [40]: tot[:10]

Out[40]:

E 368.0

X 364.0

L 346.0

O 343.0

Q 340.0

M 338.0

J 337.0

F 335.0

K 334.0

H 330.0

dtype: float64

TextParser还有一个get_chunk方法,它使你可以读取任意大小的块。

三、小结

type examplesex1.csv#windowsx系统下cmd,记得斜杠是向右下

df = pd.read_csv('examples/ex1.csv')

pd.read_table('examples/ex1.csv', sep=',')

pd.read_csv('examples/ex2.csv', header=None)

pd.read_csv('examples/ex2.csv', names=['a', 'b', 'c', 'd', 'message'])#命名

pd.read_csv('examples/ex2.csv', names=names, index_col='message')#按列表命名行

parsed = pd.read_csv('examples/csv_mindex.csv',index_col=['key1', 'key2'])#层次化索引

list(open('examples/ex3.txt'))

result = pd.read_table('examples/ex3.txt', sep='s+')#s匹配任何空白字符,+表示至少一个字符

pd.read_csv('examples/ex4.csv', skiprows=[0, 2, 3])#跳过行

pd.isnull(result)

result = pd.read_csv('examples/ex5.csv', na_values=['NULL'])

sentinels = {'message': ['foo', 'NA'], 'something': ['two']}#末列foo转NaN,一列two转NaN

pd.options.display.max_rows = 10

pd.read_csv('examples/ex6.csv', nrows=5)#读取5行

chunker = pd.read_csv('examples/ex6.csv', chunksize=1000)#分块读取

tot = tot.add(piece['key'].value_counts(), fill_value=0)

tot = tot.sort_values(ascending=False)

·后记

分三天,在每天做一百余题+整理错题+上班的前提下完成了这节,累成皮皮虾。

文中大部分带#的内容都是我加进去的,所有代码都是经过ipython去跑过的,所以比较耗时间。期间还去一些量化网站平台搭建了一些模型跑了一下,搭建用了比较长的时间,但是还是搭起来了。

设计的量化模型在期货市场的表现还不错,可以关注一下我的其他文章。

欢迎点赞·评论·分享·收藏·浇筑树苗

(o・ェ・o)ノ r (苗·lv.0)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值