Bootstrap

Python之数据载入、存储及文件格式

本博客为《利用Python进行数据分析》的读书笔记,请勿转载用于其他商业用途。

1. 文本格式数据的读写

输入和输出通常有以下几种类型:

  • 读取文本文件及硬盘上其他更高效的格式文件
  • 从数据库载入数据
  • 与网络资源进行交互(比如Web API)

将表格类型数据读取为DataFrame对象是pandas的重要特性。下表总结了部分实现该功能的函数,read_csvread_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)开始:
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  
;