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

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值