5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

csvファイルを書き出すならpandasよりcsvモジュールが速い?【違います】

Last updated at Posted at 2019-05-26

内容間違ってます。正しい内容はコメントにあり

正しい内容はこちらこちら。両方ともこの投稿へのコメントです。
以下、記事の内容は間違っていますが、誰かが同じ勘違いをしてもこれを読んでミスに気づくよう残しておきます。

CSVモジュールはpandasの数10倍速い?

読書記録をつけるため、csvファイルに1行ずつ追記していく単純な関数をPython3で作りました。pythonでは標準ライブラリにcsvモジュールがあるほか、pandasでもcsvに書き出せるということで、速度計測しました。

pandas
%%timeit

from time import strftime
import pandas as pd


def readlog(title=None, impression=None, key=None, page=0, author=None, time=strftime('%Y/%m/%d'), url=None):
  df = pd.DataFrame([title,impression,key,page,author,time,url]).T
  df.to_csv('readlog.csv', mode='a', header=False)
      
readlog(title='monty', impression='awesome', author='python', key='Spanish Inquisition')

# 1000 loops, best of 3: 878 µs per loop
csvモジュール
%%timeit

import csv
from time import strftime
 
def rdlog(title=None, impression=None, key=None, page=0, author=None, time=strftime('%Y/%m/%d'), url=None):
  with open('rdlog.csv', mode='a') as f:
    writer = csv.writer(f)
    writer.writerow([title, impression, key, page, author, time, url])
    
rdlog(title='monty', impression='awesome', author='python', key='Spanish Inquisition')

# 10000 loops, best of 3: 26.3 µs per loop

結果は
pandas
1000 loops, best of 3: 878 µs per loop
csvモジュール
10000 loops, best of 3: 26.3 µs per loop

Pandasを使いこなせてない可能性

pandasでググると、実行速度を爆速化する方法を説明した記事が複数個ヒットしたので、単に下手な使い方をしているだけかもしれません。
またあとで確認したいと思います。

##追記
pd.DataFrameのインスタンス生成がオーバーヘッドになっているとのご指摘を受けたのでチェック。比べると確かに重い…!

DataFrameインスタンス生成とリストの速度計測
%timeit df = pd.DataFrame(['a', 'awesome', '23', None]).T
# 1000 loops, best of 3: 344 µs per loop

%timeit lst = ['a', 'awesome', '23', None]
# 10000000 loops, best of 3: 103 ns per loop

オーバーヘッドはここだけ?→間違い判明

では、この箇所以外は問題ないかと言うと、そうでもありませんでした。
pd.DataFrame.to_csvもまた、csvモジュールよりベストな結果では30倍遅いという結果に(下記3と4)。計測方法などに不備がありましたら、お知らせください。すごく助かります。

以下、コードとその下に %timeitの計測結果です。

  1. DataFrameからリストに変換して、csvモジュールで書き込み。セル全体の実行時間を計測。
  2. リストからDataFrameに変換して、pd.DataFrame.to_csvで書き込み。セル全体の実行時間を計測。
  3. csvモジュールで書き込みだけする関数を作り、実行時間を計測。
  4. pd.DataFrame.to_csvの実行時間を計測。
1.DataFrame→List
%%timeit

df = pd.DataFrame(['a', 'awesome', '23', None])
lst = df.values.tolist()

with open('test.csv', mode='a') as f:
  writer = csv.writer(f)
  writer.writerow(lst)
# 1000 loops, best of 3: 285 µs per loop

1000 loops, best of 3: 285 µs per loop(DataFrame→List)

2.List→DataFrame
%%timeit 

lis = ['a', 'awesome', '23', None]
df = pd.DataFrame(lis).T

df.to_csv('pdtest.csv', 'a')
# 1000 loops, best of 3: 1.01 ms per loop

1000 loops, best of 3: 1.01 ms per loop(List→DataFrame)

3.pd.DataFrame.to_csv
%timeit df.to_csv('pdtest.csv', 'a')
# 1000 loops, best of 3: 613 µs per loop

1000 loops, best of 3: 613 µs per loop(pd.DataFrame.to_csv)

4.csvモジュール
def csvopen():
  with open('test.csv', mode='a') as f:
    writer = csv.writer(f)
    writer.writerow(lst)
    
    
%timeit csvopen()
# 10000 loops, best of 3: 22.2 µs per loop

10000 loops, best of 3: 22.2 µs per loop(csvモジュール)

5
2
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?