パンダのread_csv low_memoryおよびdtypeオプション


320

電話するとき

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この問題を解決するのですか?


2
この警告について質問があります。言及されている列のインデックスは0ベースですか?たとえば、混合型の列4は、df [:、4]またはdf [:、3]です
maziar

@maziarは、csvを読み取るときに、デフォルトで新しい0ベースのインデックスを作成して使用します。
firelynx

回答:


432

非推奨のlow_memoryオプション

このlow_memoryオプションは適切に非推奨ではありませんが、実際には何も異なることはないので、非推奨にする必要があります[ ソース ]

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

Dtype推測(非常に悪い)

パンダは、ファイル全体が読み取られた後でのみ、列に必要なdtypeを決定できます。つまり、最後の値を読み取るときにその列のdtypeを変更しなければならないリスクがない限り、ファイル全体を読み取る前に実際に解析できるものはありません。

user_idという列がある1つのファイルの例を考えてみます。これには、user_idが常に数値である1000万行が含まれます。パンダはそれが数字だけであることを認識できないため、ファイル全体を読み取るまで、それを元の文字列として保持する可能性があります。

dtypesの指定(常に実行する必要があります)

追加

dtype={'user_id': int}

pd.read_csv()呼び出しに応じて、パンダはファイルの読み取りを開始すると、これは整数のみであることを認識します。

また、ファイルの最後の行が列に"foobar"書き込まれたuser_id場合、上記のdtypeが指定されているとロードがクラッシュすることにも注意してください。

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

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": "string"})

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

通常、dtypeは数の多いものです。詳しくは、http//docs.scipy.org/doc/numpy/reference/generated/numpy.dtype.htmlをご覧ください。

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

numpy dtypes:float、int、bool、timedelta64 [ns]、datetime64 [ns]にアクセスできます。numpyの日付/時刻のdtypeはタイムゾーンに対応していないことに注意してください。

パンダはこのdtypeのセットを独自に拡張します。

'datetime64 [ns、]'これはタイムゾーンを認識するタイムスタンプです。

基本的に列挙型(保存する整数キーで表される文字列)である「カテゴリ」

'period []' timedeltaと混同しないでください。これらのオブジェクトは実際には特定の期間に固定されています

'Sparse'、 'Sparse [int]'、 'Sparse [float]'は、スパースデータまたは '多数の穴があるデータ'の場合NaNまたはNoneをデータフレームに保存する代わりに、オブジェクトを省略してスペースを節約します。

「間隔」はそれ自体のトピックですが、その主な用途は索引付けです。詳細はこちら

'Int8'、 'Int16'、 'Int32'、 'Int64'、 'UInt8'、 'UInt16'、 'UInt32'、 'UInt64'は、numpyバリアントとは異なり、すべてnull可能なパンダ固有の整数です。

'string'は、文字列データを操作するための特定のdtype .strであり、シリーズの属性へのアクセスを提供します。

'boolean'は派手な 'bool'に似ていますが、欠落データもサポートしています。

ここで完全なリファレンスを読んでください:

Pandas dtypeリファレンス

落とし穴、警告、メモ

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

dtype=unicodenumpyではa unicodeはとして表されるため、設定は何もしませんobject

コンバーターの使用

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

CSVファイルは1行ずつ処理できるため、ファイルをセグメントに分割して複数のプロセスを実行するだけで、複数のコンバーターで並行してより効率的に処理できます。これは、pandasがサポートしていないものです。しかし、これは別の話です。


6
それで、aを設定することdtype=objectはメモリ効率が良くないことを考えると、エラーを取り除く以外にそれを台無しにする理由はありますか?
zthomas.nc 2016

6
@ zthomas.ncはい、パンダはコラムの内容をテストする必要はありません。ロード(ただし、負荷後のどれもが完了)しながら、理論的には、いくつかのメモリを節約し、理論的には、ディスクI / Oからの通知がボトルネックになりませんいくつかのCPUサイクルを(セーブ。
firelynx

5
「また、注目に値するのは、ファイルの最後の行でuser_id列に「foobar」が書き込まれている場合、上記のdtypeが指定されていると、ロードがクラッシュすることです。 " クラッシュする代わりにこの行を破棄するために使用できる「強制」オプションはありますか?
すずめ

5
@sparrowがあるかもしれませんが、前回使用したときにバグがありました。それはパンダの最新バージョンで修正されるかもしれません。error_bad_lines=False, warn_bad_lines=Trueトリックを行う必要があります。ドキュメントには、Cパーサーでのみ有効であると記載されています。また、デフォルトのパーサーはNoneであるため、デフォルトのパーサーがどれであるかがわかりにくくなっています。
firelynx

5
@nealmcb nrows=100引数としてでデータフレームを読み取り、取得したdtype df.dtypesを確認することができます。ただし、これらのdtypeを使用してデータフレーム全体を読み取るときは、必ず実行して、try/except誤ったdtype推測をキャッチしてください。あなたが知っているデータは汚れています。
firelynx 2016

50

試してください:

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

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

dtype:タイプ名または列の辞書->タイプ

low_memoryについては、デフォルトではTrueでありまだ文書化されていません。私はその関連性はないと思います。エラーメッセージは一般的なものであるため、low_memoryをいじる必要はありません。これがお役に立てば幸いです。さらに問題が発生した場合はお知らせください


1
dtype=unicode生成された追加:NameError: name 'unicode' is not defined。しかしunicode、( 'unicode'のように)引用符を入れるとうまくいくようです!
sedeh

5
@sedeh dtypesをpythonタイプまたはとして指定できますnumpy.dtype('unicode')。dtypeオプションに文字列を指定するとnumpy.dtype()、デフォルトでファクトリー経由でキャストしようとします。指定して'unicode'も実際には何も行われませんobjects。ユニコードは単にに変換されます。取得しますdtype='object'
firelynx 2015

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

これで問題が解決するはずです。CSVから180万行を読み取るときに、まったく同じエラーが発生しました。


51
これはエラーを沈黙させますが、実際には何も変更しません。
firelynx

2
1.5GBデータファイルの実行中に同じ問題が発生します
Sitz Blogz

18

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

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})

2

〜400MBのファイルで同様の問題が発生しました。セッティングlow_memory=Falseは私にとってはトリックでした。最初に簡単なことを行います。データフレームがシステムメモリよりも大きくないことを確認し、再起動してRAMをクリアしてから次に進みます。それでもエラーが発生する場合は、.csvファイルに問題がないことを確認し、Excelで簡単に確認して、明らかな破損がないことを確認してください。元のデータが壊れると、大混乱を引き起こす可能性があります...


1

巨大なcsvファイル(600万行)を処理するときに、同様の問題に直面していました。3つの問題がありました:1.ファイルに奇妙な文字が含まれている(エンコードを使用して修正)2.データ型が指定されていません(dtypeプロパティを使用して修正)3.上記を使用しても、file_formatに関連する問題を解決できませんでした。ファイル名に基づいて定義(try .. except ..を使用して修正)

df = pd.read_csv(csv_file,sep=';', encoding = 'ISO-8859-1',
                 names=['permission','owner_name','group_name','size','ctime','mtime','atime','filename','full_filename'],
                 dtype={'permission':str,'owner_name':str,'group_name':str,'size':str,'ctime':object,'mtime':object,'atime':object,'filename':str,'full_filename':str,'first_date':object,'last_date':object})

try:
    df['file_format'] = [Path(f).suffix[1:] for f in df.filename.tolist()]
except:
    df['file_format'] = ''

-1

これは、と私のために働いたlow_memory = Falseデータフレームをインポート中。それは私のために働いたすべての変更です:

df = pd.read_csv('export4_16.csv',low_memory=False)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.