第37单元 掌握 pandas 的文件读写功能
即使你想不出使用pandas的理由,你仍然会被pandas的文件读写(即输入和输出)功能所折服。pandas的输入和输出功能一方面可以实现frame和series之间的数据交换,另一方面能实现CSV文件、表格文件、固定宽度文件、JSON文件(在第15单元已经讨论过)、操作系统剪贴板等之间的数据交换。pandas支持:
自动索引和列名提取
数据类型推断、数据转换和缺失数据的检测
日期时间解析
消除“不干净的”数据(跳过行、页脚和评论;处理数千个分隔符)
数据分块
读取CSV和表格文件
函数read_csv()根据文件名或打开的文件句柄,从指定的CSV文件中读取一个frame。该函数具有近五十个可选参数,它是处理CSV文件的瑞士军刀。我们自然不会再使用CSV读取器reader()了(参阅第14单元,也许现在可以抛弃它们了)。read_csv()函数的部分重要参数如下。
sep或delimiter:列分隔符。read_csv()的这个参数可以接受正则表达式(例如r"\s+"表示的“任意多个空白”)。
header:作为列名的行号。如果你有自己的列名列表,则传递None。
index_col:作为索引的列名。如果传递False,则pandas将生成一个默认数字索引。
skiprows:要跳过的文件头行数或行号列表。
thousands:表示大数时使用的千位分隔符。
names:列名列表。
na_values:用于处理缺失数据的字符串或字符串列表。如果要为不同的列使用不同的字符串(例如,缺失数据为字符串就替换为"n/a",缺失数据为数值就替换为-1),可以传递一个字典,字典的值为要使用的字符串,字典的键为列名。
我们来看看美国的各州和人口普查局的地区组成的列表的导入过程(第36单元第2小节)。原始的CSV文件具有规则而稀疏的结构:
Northeast,New England,Connecticut ,,Maine ,,Massachusetts ,,New Hampshire ,,Rhode Island ,,Vermont Northeast,Mid-Atlantic,New Jersey ,,New York ,,Pennsylvania «more states»
它没有标题行,并且有许多空的单元格,不过我们知道如何填充列名和空单元格:
regions = pd.read_csv("code/regions.csv", header=None, names=("region", "division", "state")) state2reg_series = regions.ffill().set_index("state")["region"] state2reg_series.head() ➾ state ➾ Connecticut Northeast ➾ Maine Northeast ➾ Massachusetts Northeast ➾ New Hampshire Northeast ➾ Rhode Island Northeast ➾ Name: region, dtype: object
原先的state2reg是一个字典,不是一个series,不过pandas具有几乎适用于所有情况的转换函数:
state2reg = state2reg_series.to_dict() ➾ {'Washington': 'West', 'South Dakota': 'Midwest', «more states»}
函数to_csv()将一个frame或一个series写到CSV文件中。
函数read_table()根据文件名或打开的文件句柄,从指定的表格文件中读取一个frame。本质上,它是一个使用制表符(而不是一个逗号)作为默认分隔符的read_csv()函数。
分块
如果你想从大型文件中分块读取表格数据,就需要进行分块。进行分块时,只需将参数chunksize(行数)传递给函数read_csv()即可。该函数没有实际地读取行,而是返回一个可以在for循环中使用的生成器。
让文件code/regions_clean.csv具有与code/regions.csv相同的数据,但没有遗漏的地区(region)和专区(division)。让我们假装这个文件真的很大,以至于不敢一下子读完这个文件。下面的代码创建一个用于迭代的TextFileReader对象和一个累加器series,每次从文件中读取5行。对于读取的每个片断,提取出"region"列,并对列中的值进行计数。然后将计数结果加到累加器。当某个键不存在于累加器中时,通过可选参数fill_value将其简单地设置为0,以避免出现nan。
chunker = pd.read_csv("code/regionsclean.csv_", chunksize=5, header=None, names=("region", "division", "state")) accum = pd.Series() for piece in chunker: counts = piece["region"].value_counts() accum = accum.add(counts, fill_value=0) accum ➾ Midwest 12 ➾ Northeast 9 ➾ South 17 ➾ West 13 ➾ dtype: float64
读取其他文件
函数read_json()尝试从JSON文件中读取一个frame。由于JSON文件不是一般的表格,它具有一定的层次结构,因此并非总是能将JSON数据强制转换为矩形格式。
函数read_fwf()从具有固定宽度数据的文件中读取一个frame。该函数使用的参数是colspecs(一行中列的开始位置和结束位置+1的若干个元组组成的列表)或widths(列宽组成的列表)。
函数read_clipboard()从系统剪贴板中读取文本,然后将其传递给read_table()。通过将数据复制到剪贴板,可以使用此函数一次性从Web页面中提取表格。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论