概要
Python3.6とpandasの0.19.2バージョンを使った場合(共に記事作成時点で最新)を使ってファイルを読み込もうとした場合、題記の「Initializing from file failed」が発生して困ったので、原因の調査と対策方法について調べました。
発生状況
pandasのread_csvを使ってファイルを読み込もうとすると発生します。いろいろ試してみた感じ、このエラーはファイルの中身には関係なく、ファイルのパス名(ファイル名かフォルダ)に日本語(恐らくマルチバイト文字)を含む場合に発生するものと考えられ、encodingの指定等では改善できませんでした。
サンプルコード
import pandas as pd pd.read_csv("ああ.txt")
エラーメッセージ
Traceback (most recent call last): File "<ipython-input-20-883f8bac3fb5>", line 1, in <module> runfile('C:/Git/pandasTest/test.py', wdir='C:/Git/pandasTest') File "C:\ProgramData\Anaconda3\lib\site-packages\spyder\utils\site\sitecustomize.py", line 866, in runfile execfile(filename, namespace) File "C:\ProgramData\Anaconda3\lib\site-packages\spyder\utils\site\sitecustomize.py", line 102, in execfile exec(compile(f.read(), filename, 'exec'), namespace) File "C:/Git/pandasTest/test.py", line 10, in <module> pd.read_csv("ああ.txt") File "C:\ProgramData\Anaconda3\lib\site-packages\pandas\io\parsers.py", line 646, in parser_f return _read(filepath_or_buffer, kwds) File "C:\ProgramData\Anaconda3\lib\site-packages\pandas\io\parsers.py", line 389, in _read parser = TextFileReader(filepath_or_buffer, **kwds) File "C:\ProgramData\Anaconda3\lib\site-packages\pandas\io\parsers.py", line 730, in __init__ self._make_engine(self.engine) File "C:\ProgramData\Anaconda3\lib\site-packages\pandas\io\parsers.py", line 923, in _make_engine self._engine = CParserWrapper(self.f, **self.options) File "C:\ProgramData\Anaconda3\lib\site-packages\pandas\io\parsers.py", line 1390, in __init__ self._reader = _parser.TextReader(src, **kwds) File "pandas\parser.pyx", line 373, in pandas.parser.TextReader.__cinit__ (pandas\parser.c:4184) File "pandas\parser.pyx", line 669, in pandas.parser.TextReader._setup_parser_source (pandas\parser.c:8471) OSError: Initializing from file failed
推定原因
ソースコードを追いかけていくと、pandas.ioの中のparser.pyにおいて、CParserWrapper起動時に呼び出されるファイル「parser.cp36-win_amd64.pyd」がファイル読み込みに対応していて、この中に何かしらの不具合があるだろうということが分かりました。ただし、pydファイル(コンパイル済み)となっているため、このファイル自体の修正はバージョンアップを待つほかなさそうです。
対策方法
簡単にできる対策方法として、以下の2つを見つけました。
- 読み込みエンジンにc(デフォルト)ではなく’python’を指定する。
- ファイル名をマルチバイトを含まない表記にリネームする
対策1:読み込みエンジンにc(デフォルト)ではなく’python’を指定する
Pandasのread_csvには、読み込みエンジンとしてc(デフォルト)だけでなく、Pythonも指定できるようになっています(参考記事)。このエンジンに’python’を指定することで、「parser.cp36-win_amd64.pyd」が使われなくなり、エラーなく読み込めるようになりました。
import pandas as pd pd.read_csv("ああ.txt", engine='python')
対策2:ファイル名をマルチバイトを含まない表記にリネームする
基本的には対策1で問題ないと思いますが、読み込みエンジンとして’python’を指定するとファイル読み込み速度が若干低下するため、対策するために強引にファイル名をリネームする方法が考えられます。かなり力技感がありますが、下記のようなスクリプトで実現できます。
(変換部分は次のサイト様を参考にしました。:Programming Magic様のサイト)
import pandas as pd import os #元のパス名 path = "ああ.txt" #マルチバイトを取り除いたパス名(空の文字列を用意) cpath = "" for p in path: #マルチバイトでない場合は残す if ord(p) <= 255: cpath += p #ファイル名を変更 os.rename(path, cpath) #変更したファイル名で読み込み df = pd.read_csv(cpath)
まとめ
Python3.6とpandasの0.19.2で「Initializing from file failed」が発生する原因は、「parser.cp36-win_amd64.pyd」がマルチバイトに対応していないことが(おそらく)原因ということが分かりました。また、その対策としては正式にはアップデート待ちなものの、engineに’python’を指定するか、パスからマルチバイトを除外すれば応急処置となることが分かりました。