在Python Pandas中对CSV应用GZIP压缩

68

我正在尝试使用以下代码将Python Pandas数据框写入gzip压缩的CSV文件:

import pandas as pd
import datetime
import csv
import gzip

# Get data (with previous connection and script variables)
df = pd.read_sql_query(script, conn)

# Create today's date, to append to file
todaysdatestring = str(datetime.datetime.today().strftime('%Y%m%d'))
print todaysdatestring

# Create csv with gzip compression
df.to_csv('foo-%s.csv.gz' % todaysdatestring,
      sep='|',
      header=True,
      index=False,
      quoting=csv.QUOTE_ALL,
      compression='gzip',
      quotechar='"',
      doublequote=True,
      line_terminator='\n')

这只是创建一个名为'foo-YYYYMMDD.csv.gz'的csv文件,而不是一个实际的gzip归档文件。

我也尝试过添加以下内容:

#Turn to_csv statement into a variable
d = df.to_csv('foo-%s.csv.gz' % todaysdatestring,
      sep='|',
      header=True,
      index=False,
      quoting=csv.QUOTE_ALL,
      compression='gzip',
      quotechar='"',
      doublequote=True,
      line_terminator='\n')

# Write above variable to gzip
 with gzip.open('foo-%s.csv.gz' % todaysdatestring, 'wb') as output:
   output.write(d)

还是不起作用。 有任何想法吗?


6
使用compression='gzip'参数调用df.to_csv函数可以为我生成一个gzip档案。我使用了与您相同的关键字参数。您使用的是哪个版本的pandas?请查看pd.__version__的输出来确定这一点。似乎gzip功能是在0.17.1版本中实现的,但是在早期版本中尝试使用它不会产生错误。 - root
以下是一些经过测试的例子。实际上,我建议您切换到HDF5 - 它更快速、更方便! - MaxU - stand with Ukraine
@root,那就是问题所在了!我从命令行运行了easy_install --upgrade pandas并将其从16.1升级到18.1,从而使顶部部分的“#创建带有gzip压缩的csv”代码按预期工作。 我应该编辑 / 删除主帖以反映这一点吗? - user2752159
我会把我的评论写成一个答案,你可以接受它。 - root
4个回答

94

使用 df.to_csv() 并加上关键字参数 compression='gzip' 应该可以生成一个 gzip 压缩文件。我使用和您相同的关键字参数进行了测试,结果正常。

您可能需要升级 pandas,因为 gzip 直到版本 0.17.1 才被实现。但在较旧的版本上尝试使用它不会引发错误,只会生成普通的 csv 文件。您可以通过查看 pd.__version__ 的输出来确定当前安装的 pandas 版本。


如果您正在使用Jupyter笔记本电脑,请键入“?df.to_csv”并阅读文档。 @cᴏʟᴅsᴘᴇᴇᴅ - rpanai
6
希望说明一下一个已记录的限制:compression=gzip 只在 .to_csv() 的第一个参数是文件名时有效,如果第一个参数是文件对象,则不起作用。 - shawnzhu
3
注意:由于连接gunzip会产生另一个有效的gunzip,因此您可以重复执行df.to_csv(filename, compression='gzip', mode='a')将数据框组合成一个大的gunzipped文件。如果您的数据不适合内存,则非常有用。 - BallpointBen
2
请注意,默认值 compression'infer',这意味着压缩类型将从文件后缀推断出来,因此您只需在文件名后添加 .gz 即可。 - dopexxx
df.to_csv(filename, compression='gzip', mode='a') 这是我第一次尝试,只有在 gzip 文件中的 csv 文件被更新。对我来说似乎追加不起作用。每行数据在函数调用时只读取一次到 df 中,因此应该使用追加功能重复执行此操作。 - Nagasri Varma
此外,现在也支持.bz2格式;这是一种更快、更小、更广泛的工具。 - dsz

54

使用pandas非常容易完成。

import pandas as pd

pandas dataframe 以 gunzip 压缩的 csv 格式写入磁盘

df.to_csv('dfsavename.csv.gz', compression='gzip')

从磁盘中读取

df = pd.read_csv('dfsavename.csv.gz', compression='gzip')

11

来自文档

import gzip
content = "Lots of content here"
with gzip.open('file.txt.gz', 'wb') as f:
    f.write(content)

使用 pandas

import gzip


content = df.to_csv(
      sep='|',
      header=True,
      index=False,
      quoting=csv.QUOTE_ALL,
      quotechar='"',
      doublequote=True,
      line_terminator='\n')

with gzip.open('foo-%s.csv.gz' % todaysdatestring, 'wb') as f:
    f.write(content)

这里的技巧在于,如果您不传递文件名,to_csv 将输出文本。然后,您只需将该文本重定向到 gzipwrite 方法。


这比直接将参数传递给gzip更有效吗?我目前(在我打字的时候)正在从旧数据库中提取大约40GB的表,并决定只是循环遍历每个表并使用compression ='gzip'写出每个迭代,但想知道是否应该使用这个答案。 - Umar.H

1
with gzip.open('foo-%s.csv.gz' % todaysdatestring, 'wb') as f:
    f.write(df.to_csv(sep='|', index=False, quoting=csv.QUOTE_ALL))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接