您的位置:首页 > 编程语言 > Python开发

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

2018-02-01 15:17 573 查看

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

如果不能将数据导入导出Python,本书所介绍的这些工具就没什么大用

内容提要

读取文本格式数据

逐块读取文本文件

将数据写出到文本格式

手工处理分隔符格式

读写文本格式的数据

path = 'C:\\...\\ex1.csv'


跟前面美国婴儿出生数据一文中相似,这个地方打开文件需要借助os模块(这与Python版本是有所关联的)

import os

df = pd.read_csv(os.path.basename(path))

df
Out[12]:
1  2  3  4
0  a  b  a  b
1  a  b  c  a
2  2  3  4  5


如上,如果本身数据就是用
<Tab>
隔开的,就可以不传入参数
sep
,但是如果数据是由其他的分隔符,例如 逗号 ,就需要使用参数
sep
,如下文

df = pd.read_csv(os.path.basename(path), sep=',')

df
Out[16]:
1  2  3  4
0  a  b  a  b
1  a  b  c  a
2  2  3  4  5


通过给names赋值,可以指定列标签

names = list('abcde')

pd.read_csv(os.path.basename(path), names=names)
Out[24]:
a  b  c  d      e
0  1  2  3  4  hello
1  a  b  a  b  world
2  a  b  c  a    asd
3  2  3  4  5     hi


通过指定index_col可以指定行标签,如果传给index_col的是数组,则可以进行层次化索引(这里的索引都是原始数据中就包含的)

parsed = pd.read_csv(os.path.basename(path),index_col=['key1', 'key2'])

parsed
Out[28]:
value1  value2
key1 key2
one  a          2       3
b          1       6
two  a          2       3
b          3       4


有些表格可能不是用固定的分隔符来分隔字段的,对于这种情况,可以编写一个正则表达式作为read_table的分隔符,比如下面这个例子

list(open(os.path.basename(path)))
Out[10]: [' value1 value2\n', 'one a 2 3\n', 'one b  6\n', 'two a 2 3\n', 'two b 3 4\n']

result = pd.read_table(os.path.basename(path), sep='\s+')

result
Out[12]:
value1  value2
one a       2     3.0
b       6     NaN
two a       2     3.0
b       3     4.0


上面这个例子中,由于列名的数量比列的数量少一。所以read_table推断第一列应该是DataFrame的索引

缺省数据经常要么没有(空字符串),要么有某个标记值表示,如下

runfile('C:/...', wdir='C:/...')
value1   value2
one  a        2.0       3
b        NaN       6
two  a        2.0       3
b        3.0       4


值得注意的是,如果数据中有空格,那么不能算作缺省值

read_csv中,参数na_value可以接受一组表示缺省值的字符串,例如在文件中某个改成NULL

df = pd.read_csv(os.path.basename(path), na_values=['NULL'])

df
Out[25]:
value1   value2
one  a        2.0       3
b        NaN       6
two  a        2.0       3
b        3.0       4


就像前面的pandas用法中介绍的那样,可以用一个字典为各列指定不同的NA标记值

逐块读取文本文件

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

如果只想读取几行,可以指定read_csv中的参数nrows

df = pd.read_table(os.path.basename(path), sep = ',', nrows = 100)


要逐块读取文件,需要设置chunkersize(行数)

chunker = pd.read_table(os.path.basename(path), sep = ',', chunksize = 100)

chunker
Out[24]: <pandas.io.parsers.TextFileReader at 0x1648d00fbe0>


read_csv返回的这个TextParser对象使你可以根据chunkersize对文件进行逐块迭代,比如下面对其一列进行聚合

tot = Series([])

for piece in chunker:
tot = tot.add(piece['Unnamed: 2'].value_counts(), fill_value=0)

tot[:10]
Out[23]:
2.0     2.0
3.0     1.0
4.0     1.0
5.0     1.0
6.0     1.0
7.0     1.0
8.0     1.0
9.0     1.0
10.0    1.0
dtype: float64


将数据写出到文本格式

可以通过DataFrame的 to_csv 方法,例如

df.to_csv(os.path.basename(path_out), sep = ',')
df2 = pd.read_csv(os.path.basename(path_out), sep=',')

df2[:10]
Out[33]:
Unnamed: 0  value1  value2  Unnamed: 2  Unnamed: 3
0           0     one      a          2.0           3
1           1     one       b         NaN           6
2           2     two      a          2.0           3
3           3     two      b          3.0           4
4           4     two      b          4.0           5
5           5     two      b          5.0           6
6           6     two      b          6.0           7
7           7     two      b          7.0           8
8           8     two      b          8.0           9
9           9     two      b          9.0          10


通过指定参数 columns 可以选择只输出特定的列,而且是以指定的顺序写入的

df.to_csv(os.path.basename(path_out), sep = ',', columns = ['value1', 'value2'])
df2 = pd.read_csv(os.path.basename(path_out), sep=',')

df3 = pd.read_table(os.path.basename(path_out), sep=',')

df3[:10]
Out[37]:
Unnamed: 0  value1 value2
0           0     NaN     a
1           1     NaN      b
2           2     NaN     a
3           3     NaN     b
4           4     NaN     b
5           5     NaN     b
6           6     NaN     b
7           7     NaN     b
8           8     NaN     b
9           9     NaN     b


同样Series也有输出到csv的方法,也叫 to_csv

dates = pd.date_range('1/1/2000', periods=7)

ts = Series(np.arange(7), index=pd.date_range('1/1/2000', periods=7))

path = 'C:\\...\\Series.csv'

ts.to_csv(os.path.basename(path))

df = pd.read_table(os.path.basename(path), sep = ',')

df
Out[47]:
2000-01-01  0
0  2000-01-02  1
1  2000-01-03  2
2  2000-01-04  3
3  2000-01-05  4
4  2000-01-06  5
5  2000-01-07  6


如果我们希望用第一列作为索引,而且数据本身就没有header行,可以通过改变参数得到

Series.from_csv(os.path.basename(path), parse_dates=True)
Out[48]:
2000-01-01    0
2000-01-02    1
2000-01-03    2
2000-01-04    3
2000-01-05    4
2000-01-06    5
2000-01-07    6
dtype: int64


手工处理分隔符格式

大部分存储在磁盘上的表格型数据都能用pandas.read_table 进行加载。然而,有时还是需要做一些手工处理。

对于任何单字符分隔符文件,可以直接使用Python内置的csv模块。将任意已打开的文件或文件型对象传给csv.reader:

import csv

path = path = 'C:\\...\\ex1.csv'

f = open(os.path.basename(path))

reader = csv.reader(f)

for line in reader:
print(line)

['one ', 'a ', '2', '3']
['one ', 'b', 'NULL', '6']
['two ', 'a ', '2', '3']
['two ', 'b ', '3', '4']
['two ', 'b ', '4', '5']
['two ', 'b ', '5', '6']


现在,为了使数据格式合乎要求,需要做一些整理工作

lines = list(csv.reader(open(os.path.basename(path))))

header, values = lines[0],lines[1:]

data_dict = {h:v for h,v in zip(header, zip(*values))}

data_dict
Out[57]:
{'2': ('NULL', '2', '3', '4', '5'),
'3': ('6', '3', '4', '5', '6'),
'a ': ('b', 'a ', 'b ', 'b ', 'b '),
'one ': ('one ', 'two ', 'two ', 'two ', 'two ')}


后面 JSON数据, XML和HTML:Web信息搜集,二进制数据格式,使用HDF5格式,读取Microsoft Excel文件,使用HTML和Web API,使用数据库,存取MongoDB中的数据 内容比较细,准备以后用到的时候进行查阅

大功告成

利用Python进行数据分析本书本次阅读到此,之后章节例如金融数据等到有时间,有需求再详细阅读

Never mind happiness, do your mission
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息