本博客为《利用Python进行数据分析》的读书笔记,请勿转载用于其他商业用途。
文章目录
1. 文本格式数据的读写
输入和输出通常有以下几种类型:
- 读取文本文件及硬盘上其他更高效的格式文件
- 从数据库载入数据
- 与网络资源进行交互(比如Web API)
将表格类型数据读取为DataFrame对象是pandas的重要特性。下表总结了部分实现该功能的函数,read_csv
和read_table
可能是后期我们使用最多的函数。
表:Pandas的解析函数
函数 | 描述 |
---|---|
read_csv | 从文件、URL或文件型对象读取分隔好的数据,逗号是默认分隔符 |
read_table | 从文件、URL或文件型对象读取分隔好的数据,制表符(‘t/’)是默认分隔符 |
read_fwf | 从特定宽度格式的文件中读取数据(无分隔符) |
read_clipboard | read_table的剪贴版本,在将表格从Web页面上转换成数据时有用 |
read_excel | 从Excel的XLS或XLSX文件中读取表格数据 |
read_hdf | 读取用pandas存储的HDF5文件 |
read_html | 从HTML文件中读取所有表格数据 |
read_json | 从JSON(JavaScript Object No tation)字符串中读取数据 |
read_msgpack | 读取MessagePack二进制格式的pandas数据 |
read_pickle | 读取以Python pickle格式存储的任意对象 |
read_sas | 读取存储在SAS系统中定制存储格式的SAS数据集 |
read_sql | 将SQL查询的结果(使用SQLAlchemy)读取为pandas的DataFrame |
read_stata | 读取Stata格式的数据集 |
read_feather | 读取Feather二进制格式 |
这些函数的可选参数主要有以下几种类型:
- 索引
可以将一或多个列作为返回的DataFrame,从文件或用户处获得列名,或者没有列名。 - 类型推断和数据转换
包括用户自定义的值转换和自定义的缺失值符号列表 - 日期时间解析
包括组合功能,也包括将分散在多个列上的日期和时间信息组合成结果中的单个列。 - 迭代
支持对大型文件的分块迭代。 - 未清洗数据问题
跳过行、页脚、注释以及其他次要数据,比如使用逗号分隔千位的数字。
由于现实世界中的数据非常混乱,随着时间推移,一些数据加载函数(尤其是read_csv
)的可选参数变得非常复杂。pandas的在线文档有大量示例展示这些参数是如何工作的。如果你在读取某个文件时遇到了困难,在文档中可能会有相似的示例帮助你如何找到正确的参数。
一些数据载入函数,比如pandas.read_csv
,会进行类型推断,因为列的数据类型并不是数据格式的一部分。那就意味着我们不必指定哪一列时数值、整数、布尔值或字符串。其他的数据格式,比如HDF5、Feather和msgpack在格式中已经存储了数据类型。
处理日期和其他自定义类型可能需要额外的努力。我们从一个小型的逗号分隔符文本文件(csv)开始:
由于这个文件时逗号分隔的,我们可以使用read_csv将它读入一个DataFrame:
df = pd.read_csv('C:/ex1.csv')
print(df)
#
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
,并制定分隔符:
df = pd.read_table('C:/ex1.csv', sep=',')
print(df)
#
a b c d message
0 1 2 3 4 hello
1 5 6 7 8 world
2 9 10 11 12 foo
有些文件并不包含表头,比如:
要读取该文件,我们需要选择一些选项。你可以允许pandas自动分配默认列名,也可以自己指定列名:
df = pd.read_csv('C:/ex2.csv', header=None)
print(df)
#
0 1 2 3 4
0 1 2 3 4 hello
1 5 6 7 8 world
2 9 10 11 12 foo
df = pd.read_csv('C:/ex2.csv', names=['a', 'b', 'c', 'd', 'message'])
print(df)
#
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的列为索引,或将’message’传给参数index_col
:
names = ['a', 'b', 'c', 'd', 'message']
df = pd.read_csv('C:/ex2.csv', names=names, index_col='message')
print(df)
#
a b c d
message
hello 1 2 3 4
world 5 6 7 8
foo 9 10 11 12
如果我们想要从多个列中形成一个分层索引,需要传入一个包含序列号或列名的列表:
parsed = pd.read_csv('C:/csv_mindex.csv', index_col=['key1', 'key2'])
print(parsed)
#
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
在某些情况下,一张表的分隔符并不是固定的,使用空白或其他方式来分隔字段,考虑如下文本文件:
data = list(open('C:/ex3.txt'))
print(data)
#
['\tA\tB\tC\n',
'aaa\t1\t2\t3\n',
'bbb\t4\t5\t6\n',
'ccc\t7\t8\t9\n',
'ddd\t10\t11\t12\n']
result = pd.read_table('C:/ex3.txt', sep='\s+')
print(result)
#
A B C
aaa 1 2 3
bbb 4 5 6
ccc 7 8 9
ddd 10 11 12
本例中,由于列名的数量比数据的列少一个,因此read_table
推断第一列应当作为DataFrame的索引。
解析函数有很多附加参数帮助你处理各种发生异常的文件格式。例如,你可以使用skiprows
来跳过第1、3、4行:
df = pd.read_csv('C:/ex4.csv', skiprows=[0, 2, 3])
print(df)
#
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:
result = pd.read_csv('C:/ex5.csv')
print(result)
#
something a b c d message
0 one 1 2 3 4 NaN
1 two 5 6 7 8 world
2 three 9 10 11 12 foo
print(pd.isnull(result))
#
something a b c d message
0 False False False False False True
1 False False False