web-dev-qa-db-ja.com

Pandas read_csv low_memoryオプションとdtypeオプション

電話をかけるとき

df = pd.read_csv('somefile.csv')

私は得ます:

/Users/josh/anaconda/envs/py27/lib/python2.7/site-packages/pandas/io/parsers.py:1130:DtypeWarning:列(4、5、7、16)の型が混在しています。インポート時にdtypeオプションを指定するか、low_memory = Falseを設定してください。

dtypeオプションがlow_memoryに関連しているのはなぜですか?また、Falseをこの問題に役立つのはなぜですか?

206
Josh

廃止予定のlow_memoryオプション

low_memoryオプションは適切に推奨されていませんが、実際には何も変わらないので、そうするべきです[ source ]

このlow_memory警告が表示されるのは、各列のdtypeを推測することはメモリを非常に必要とするためです。 Pandasは各列のデータを分析して、設定するdtypeを決定しようとします。

Dtype推測(非常に悪い)

Pandasは、ファイル全体が読み取られた後に列に格納する必要があるdtypeを決定することしかできません。これは、最後の値を読んだときにその列のdtypeを変更する必要がない限り、ファイル全体が読み込まれる前に実際には何も解析できないことを意味します。

User_idという列を持つ1つのファイルの例を考えてください。 user_idが常に数字である1000万行が含まれています。パンダはそれが数字だけであることを知ることができないので、それはそれがファイル全体を読むまでオリジナルのストリングとしてそれをおそらく保持するでしょう。

Dtypesを指定する(常に行われるべきです)

追加

dtype={'user_id': int}

pd.read_csv() 呼び出しを行うとパンダはファイルの読み込みを開始したときにそれが整数値であることを認識します。

また、ファイルの最後の行の"foobar"列にuser_idが書き込まれている場合、上記のdtypeが指定されているとロードがクラッシュする可能性があります。

Dtypesが定義されていると壊れる壊れたデータの例

import pandas as pd
try:
    from StringIO import StringIO
except ImportError:
    from io import StringIO


csvdata = """user_id,username
1,Alice
3,Bob
foobar,Caesar"""
sio = StringIO(csvdata)
pd.read_csv(sio, dtype={"user_id": int, "username": object})

ValueError: invalid literal for long() with base 10: 'foobar'

dtypesは典型的にはぎこちないものです、それらについての詳細はこちらを読んでください: http://docs.scipy.org/doc/numpy/reference/generated/numpy.dtype.html

どんなdtypeが存在しますか?

これらはパンダでも受け入れられている派手なdtypesです。

[numpy.generic,
 [[numpy.number,
   [[numpy.integer,
     [[numpy.signedinteger,
       [numpy.int8,
        numpy.int16,
        numpy.int32,
        numpy.int64,
        numpy.int64,
        numpy.timedelta64]],
      [numpy.unsignedinteger,
       [numpy.uint8,
        numpy.uint16,
        numpy.uint32,
        numpy.uint64,
        numpy.uint64]]]],
    [numpy.inexact,
     [[numpy.floating,
       [numpy.float16, numpy.float32, numpy.float64, numpy.float128]],
      [numpy.complexfloating,
       [numpy.complex64, numpy.complex128, numpy.complex256]]]]]],
  [numpy.flexible,
   [[numpy.character, [numpy.bytes_, numpy.str_]],
    [numpy.void, [numpy.record]]]],
  numpy.bool_,
  numpy.datetime64,
  numpy.object_]]

Pandasは2つのdtypeも追加しています:categoricaldatetime64[ns, tz]で、numpyでは利用できません

Pandas dtypeリファレンス

Gotchas、警告、メモ

dtype=objectを設定すると、上記の警告は表示されなくなりますが、メモリ効率は向上せず、処理効率が向上します。

dtype=unicodeを設定しても何もしません。厄介なので、unicodeobjectとして表されます。

コンバーターの使い方

@sparrowはintとして指定された列で'foobar'に遭遇したときパンダが爆発するのを避けるためにコンバーターの使用法を正しく指摘しています。私は、コンバータはパンダで使うのに本当に重くて非効率的で、そして最後の手段として使われるべきであることを付け加えたいと思います。これは、read_csvプロセスが単一のプロセスであるためです。

CSVファイルは1行ずつ処理できるため、ファイルをセグメントに分割して複数のプロセスを実行するだけで、複数のコンバーターで並列に処理することができます。パンダではサポートされていません。しかし、これは別の話です。

292
firelynx

試してください:

dashboard_df = pd.read_csv(p_file, sep=',', error_bad_lines=False, index_col=False, dtype='unicode')

パンダのドキュメントによると:

dtype:型名または列の辞書 - > type

Low_memoryに関しては、True デフォルトで であり、まだ文書化されていません。私はそれが適切だとは思わない。エラーメッセージは一般的なので、とにかくlow_memoryを台無しにする必要はありません。これが助けになることを願っていて、さらに問題があるかどうか私に知らせてください

33
hd1
df = pd.read_csv('somefile.csv', low_memory=False)

これで問題は解決するはずです。 CSVから1.8Mの行を読むとき、私は全く同じエラーを得ました。

27
Neal

Dtypeが明示的に指定されていて、そのdtypeと互換性がない混合データがある場合、firelynxによって前述されたように、ロードはクラッシュします。データがまだロードされることができるように互換性のないデータ型で値を変更するための回避策としてこのようなコンバーターを使用しました。

def conv(val):
    if not val:
        return 0    
    try:
        return np.float64(val)
    except:        
        return np.float64(0)

df = pd.read_csv(csv_file,converters={'COL_A':conv,'COL_B':conv})
12
sparrow

DataFrameのインポート中はlow_memory = Falseでうまくいきました。それが私にとってうまくいったすべての変更です。

df = pd.read_csv('export4_16.csv',low_memory=False)
0
Rajat Saxena

私は400MB以下のファイルで同様の問題を抱えていました。 low_memory=Falseを設定するとうまくいきました。最初に簡単なことをしてください、私はあなたのデータフレームがあなたのシステムメモリより大きくないことを確認します、再起動して、続行する前にRAMをクリアしてください。まだエラーが発生している場合は、.csvファイルが正常であることを確認し、Excelで簡単に調べて、明らかな破損がないことを確認します。元のデータが壊れていると、混乱を招く可能性があります。

0
Dr Nigel