Python,字典转CSV:有更快的方法吗?

3
我已经编写了一个简单的方法将字典写入CSV文件。它可以正常工作,但我想知道在速度方面是否可以改进(在我的测试中,写入1000行CSV需要6秒钟)。
我的问题是:如何改善这段代码的速度?(如果可能的话)
非常感谢您的帮助。
def fast_writer(self, f_name, text_dict):
    try:
        start = timer()
        # Windows
        if os.name == "nt":
            with open(f_name, 'w', newline='') as self._csv_file:
                self._writer = csv.writer(self._csv_file)
                for self._key, self._value in text_dict.items():
                    self._writer.writerow([self._key, self._value])

        # Unix/Linux
        else:
            with open(f_name, 'w') as self._csv_file:
                self._writer = csv.writer(self._csv_file)
                for self._key, self._value in text_dict.items():
                    self._writer.writerow([self._key, self._value])

        end = timer()
        print("[FastWriter_time] ", end - start)
    except BaseException:
        print("[ERROR] Unable to write file on disk. Exit...")
        sys.exit()
3个回答

5

如果你只是想更快地完成这个任务,pandas 已经内置了这样的方法,并且已经进行了很好的优化!例如,请看下面的代码:

import numpy as np
import pandas as pd

# This is just to generate a dictionary with 1000 values:
data_dict = {'value':[i for i in np.random.randn(1000)]}

# This is to translate dict to dataframe, and then same it
df = pd.DataFrame(data_dict)
df.to_csv('test.csv')

将字典写入数据框并将数据框写入CSV文件,大约需要0.008秒的时间。


至少在我的机器上,纯Python方法比这种方法更快。可能是因为先将数据读入DataFrame的开销所致。 - Graipher
我猜最终它将受到磁盘写入速度的限制。 - Graipher
只是确认一下 - data_dict 不是只有一行数据吗? - AustEcon

3

如果您不想使用 pandas,可以摆脱所有被存储在 self 中的变量,并将它们变为局部变量:

def fast_writer(self, f_name, text_dict):
    try:
        start = timer()
        newline = '' if os.name == "nt" else None
        with open(f_name, 'w', newline=newline) as csv_file:
            writer = csv.writer(csv_file)
            writer.writerows(text_dict.items())
        end = timer()
        print("[FastWriter_time] ", end - start)
    except BaseException as e:
        print("[ERROR] Unable to write file on disk. Exit...")
        print(e)
        sys.exit()

此外,使用writer.writerows可以一次写入多行。

在我的机器上,这种方法比pandas方法更快,使用由@sacul他们的回答中定义的测试数据:

In [6]: %timeit fast_writer("test.csv", data_dict)
1.59 ms ± 62.8 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [10]: %timeit fast_writer_pd("test.csv", data_dict)
3.97 ms ± 61.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

1
< p > Writer 对象已经有一个将行列表写入文件的方法;您不需要显式迭代。

def fast_writer(self, f_name, text_dict):
    try:
        start = timer()

        with open(f_name, 'w', newline=None) as csv_file:
            writer = csv.writer(csv_file)
            writer.writerows(text_dict.items())

        end = timer()
        print("[FastWriter_time] ", end - start)
    except Exception:
        print("[ERROR] Unable to write file on disk. Exit...")
        sys.exit()

以下是一些注释:

  1. 你不需要嗅探操作系统;newline=None 使用底层系统默认值。
  2. 如果你每次调用都要重新分配 self._writerself._csv_file,它们可能不必是实例属性;它们可以只是局部变量:writer = csv.writer(csv_file)
  3. BaseException 太过广泛;它和裸的 except 语句没有区别。使用 Exception,但考虑仅捕获 IOErrorOSError。其他异常可能表明你的代码存在错误,而不是合法的 IO 错误。

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