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