質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

1回答

1355閲覧

300kb程度の大量のcsvを高速に読み込みたい。

sasaya

総合スコア12

CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

1グッド

3クリップ

投稿2017/10/29 18:42

編集2017/10/29 19:04

###前提・実現したいこと
大量(3,574個程度)のcsvファイルを高速に読み込みたいです。
Pythonの勉強も兼ねて,現在過去10年程度の期間において、自分の作った株取引ルールが機能するかを検証するためのプログラムを作成中です。そのためにcsvで保存されたデータをなるべく早く読み込みたいです。

現在は xarrayを用いて3次元データとして扱おうとしておりますがより高速な方法がありましたら教えていただけたら幸いです。

使用しているデータは株価データ集 for 日本株時系列データ 2000年-2017年6月30日です。

###発生している問題・エラーメッセージ

Ipythonで%time , %run -p で動作時間を計測した結果
570秒~1500秒もの時間がかかっており,xarray.concat()だけで40秒程度かかっております。

一例

8383269 function calls (8141048 primitive calls) in 905.298 seconds Ordered by: internal time ncalls tottime percall cumtime percall filename:lineno(function) 25 384.667 15.387 384.667 15.387 {built-in method numpy.core.multiarray.concatenate} 1 244.721 244.721 711.806 711.806 combine.py:286(_dataarray_concat) 24 130.215 5.426 130.215 5.426 {method 'acquire' of '_thread.lock' objects} 1 55.747 55.747 904.727 904.727 read_data.py:3(<module>) 1 13.966 13.966 13.966 13.966 {built-in method pandas._libs.lib.infer_datetimelike_array} 3960 7.479 0.002 8.485 0.002 indexing.py:480(__setitem__) 11878 6.137 0.001 6.137 0.001 {built-in method pandas._libs.lib.array_equivalent_object}

###該当のソースコード

Python

1import os 2import numpy as np 3import xarray as xr 4import pandas as pd 5from multiprocessing import Pool 6import numba 7 8_path = os.path.abspath(os.path.dirname(__file__)) + '/st-jp-2000-2017.6/dd_full' 9_ref = pd.read_csv(os.path.abspath(os.path.dirname(__file__)) + '/st-jp-2000-2017.6/dd/1301.CSV', 10 index_col=0, parse_dates=True, 11 names=["Open", "High", "Low", "Close", "Volume", "margin selling", "margin debt"]) 12 13 14@numba.jit 15def in_parallel(): 16 global _path 17 files = os.listdir(_path) 18 p = Pool() 19 stock_db = (p.map(csv_to_xarray, files)) 20 p.close() 21 p.join() 22 print("loading complete") 23 return stock_db 24 25 26def in_serial(): 27 global _path 28 files = os.listdir(_path) 29 stock_db = [csv_to_xarray(file) for file in files] 30 print("loading complete") 31 return stock_db 32 33 34@numba.jit 35def csv_to_xarray(file): 36 """ 37 :type file: str 38 :rtype: DataArray 39 """ 40 global _ref 41 global _path 42 data = pd.read_csv(_path + '/' + file, index_col=0, parse_dates=True, 43 names=["Open", "High", "Low", "Close", "Volume", "margin selling", "margin debt"]) 44 45 data = adjust_index_length(data, _ref) 46 47 da = xr.DataArray(data.values.reshape(len(data.index), 1, len(data.columns)), 48 coords=[data.index, [file[0:4]], 49 ["Open", "High", "Low", "Close", "Volume", "margin selling", "margin debt"]], 50 dims=["date", "code", "values"]) 51 return da 52 53 54@numba.jit 55def adjust_index_length(data, ref): 56 """ 57 :type ref: DataFrame 58 :type data: DataFrame 59 :rtype: DataFrame 60 """ 61 time_diff = set(ref.index) - set(data.index) 62 if len(time_diff) == 0: 63 data.drop(set(data.index) - set(ref.index), inplace=True) 64 return data.sort_index() 65 66 else: 67 df = pd.DataFrame(index=time_diff, columns=["Open", "High", "Low", "Close", "Volume", 68 "margin selling", "margin debt"]) 69 df = df.append(data) 70 return df.sort_index() 71 72 73if __name__ == '__main__': # ここで この処理を行わないとサブプロセスが再帰的に生成される?(Winだけ?) 74 __spec__ = "ModuleSpec(name='builtins', loader=<class '_frozen_importlib.BuiltinImporter'>)" 75 76 print(xr.concat(in_parallel(), dim='code')) 77 #print(xr.concat(in_serial(), dim='code'))

###試したこと
multiprocessingを用いて並列に走らせてみて,ディスク使用率は常時100%になっていることを確認しました。また,numbaの使用を検討中であります。
そもそもpythonだけですべて行わず,元データの選別等をC等で行うことも検討しております。

###補足情報(言語/FW/ツール等のバージョンなど)
現在の動作環境は以下の通りです。
core i3-6100T 3.2GHz
Ram ddr3 8GB

Windows 10
Anaconda
Python 3.6

今後 core i7 ないし Ryzen 7を積んだpcに乗り換える予定があります。

退会済みユーザー👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

自分の作った株取引ルールが機能するかを検証するためのプログラムを作成中です。
使用しているデータは株価データ集 for 日本株時系列データ 2000年-2017年6月30日です。

わざわざ低速なフォーマットを採用するメリットは一つもありません。
CSVを採用するケースなんて、非エンジニアの上司や顧客がExcelで見ないとやだやだって駄々こねたときだけです。

この馬鹿げた処理速度の原因の殆どは読み込みとソートに終始しているので、SQLiteに任せたほうが間違いなく速いです。
ローカルでソート処理等を書いてはいけません。
CSVファイル -> SQLite等の高速なフォーマットに一度移しておき、SQL文をつかって絞込やソートを行いましょう。

検証フェイズが終わった後本番で使う時の事を考えた場合、
株価は毎日のように更新されますが、SQLiteに変換するプログラムを用意してまわしておけば良いでしょう。

投稿2017/10/29 23:32

miyabi-sun

総合スコア21158

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sasaya

2017/10/30 06:24 編集

やはり、横着せずにsqlにした方がいいんですね。ありがとうございます 別件ですが 元々ソートされているものに対して set()で集合にして取った差をインデックスにDataFrameを作ると何故ソートされてない状態になってしまうのかというのが現在ちょっと引っかかっています。
miyabi-sun

2017/10/30 02:45

http://uxmilk.jp/14834 Pythonに関しては詳しくないのでブログ記事の引用で失礼します。 setは順番の概念を持たないので、おもちゃ箱のような空間に無造作に放り込まれるのでしょうね。 その後重複チェック処理にかけられますので、メモリ空間上に設置されたアイテムはこねくり回されてぐちゃぐちゃになるのだろうと「完全に憶測」ですが想像してます。 ソート済みの要素を重複排除の為だけにsetを使うのはやめたほうが良さそうですね。
sasaya

2017/10/30 13:00

大変丁寧でかつ迅速な回答をいただき、ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問