Pandalar read_csv low_memory ve dtype seçenekleri


320

Ararken

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

Alırım:

/Users/josh/anaconda/envs/py27/lib/python2.7/site-packages/pandas/io/parsers.py:1130: DtypeUyarı: Sütunların (4,5,7,16) karışık türleri vardır. İçe aktarmada dtype seçeneğini belirtin veya low_memory = False olarak ayarlayın.

dtypeSeçenek neden ile ilgilidir low_memoryve neden Falsebu soruna yardımcı olur?


2
Bu uyarı hakkında bir sorum var. Bahsedilen sütunların indeksi 0 tabanlı mı? Örneğin, karışık bir türe sahip sütun 4, df [:, 4] veya df [:, 3]
maziar

@maziar bir csv okurken, varsayılan olarak yeni bir 0 tabanlı dizin oluşturulur ve kullanılır.
firelynx

Yanıtlar:


432

Kullanımdan kaldırılmış low_memory seçeneği

low_memorySeçenek düzgün kaldırılan değil, ama aslında farklı bir şey yapmaz çünkü, olması gerektiği [ kaynak ]

Bu low_memoryuyarıyı almanızın nedeni , her sütun için dtype tahmininin çok bellek gerektirmesidir. Pandalar, her sütundaki verileri analiz ederek hangi dtype'un ayarlanacağını belirlemeye çalışır.

Tipi Tahmin (çok kötü)

Pandalar, yalnızca tüm dosya okunduğunda bir sütunun hangi dtype'a sahip olması gerektiğini belirleyebilir. Bu, son değeri okurken söz konusu sütunun dtype'sini değiştirmek zorunda kalmadığınız sürece, tüm dosya okunmadan önce hiçbir şeyin gerçekten ayrıştırılamayacağı anlamına gelir.

User_id adlı bir sütunu olan bir dosya örneğini düşünün. User_id öğesinin her zaman sayı olduğu 10 milyon satır içerir. Pandalar sadece sayılar olduğunu bilemediğinden, tüm dosyayı okuyana kadar orijinal dizeler olarak tutacaktır.

Türleri belirtme (her zaman yapılmalıdır)

ekleme

dtype={'user_id': int}

için pd.read_csv()dosyayı okumaya başladığında çağrı bu sadece tamsayı olduğunu, pandalar biliyoruz yapacaktır.

Ayrıca kayda değer dosyasındaki son satırı olurdu eğer ki "foobar"yazılı user_idsütunda yukarıdaki d_type belirtildi yükleme çökmesine neden oluyordu.

Dtypes tanımlandığında kırılan bozuk veri örneği

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'

dtypes genellikle tipik bir şeydir, onlar hakkında daha fazla bilgiyi buradan edinebilirsiniz: http://docs.scipy.org/doc/numpy/reference/generated/numpy.dtype.html

Hangi türler var?

Numpy türlerine erişebiliyoruz: float, int, bool, timedelta64 [ns] ve datetime64 [ns]. Nümerik tarih / saat türlerinin saat diliminden haberdar olmadığını unutmayın .

Pandalar bu dtypes setini kendi ile genişletir:

'datetime64 [ns,]' Saat diliminden haberdar olan bir zaman damgasıdır.

esasen bir enum olan 'kategori' (kaydetmek için tamsayı tuşlarıyla gösterilen dizeler)

'period []' Bir zaman dilimiyle karıştırılmaması için bu nesneler aslında belirli zaman periyotlarına bağlanır

'Seyrek', 'Seyrek [int]', 'Seyrek [şamandıra]' seyrek veriler veya 'İçinde çok fazla delik bulunan veriler' içindir. Veri çerçevesine NaN veya Hiçbiri kaydetmek yerine, nesneleri atlar .

'Aralık' başlı başına bir konudur ancak asıl kullanım endeksleme içindir. Daha fazlasını burada görün

'Int8', 'Int16', 'Int32', 'Int64', 'UInt8', 'UInt16', 'UInt32', 'UInt64', numpy değişkeninin aksine null olabilecek pandaya özgü tamsayılardır.

'dize', dize verileriyle çalışmak için belirli bir dptir ve .str ve dizideki özniteliğe .

'boolean' numpy 'bool' gibidir ancak eksik verileri de destekler.

Referansın tamamını buradan okuyun:

Pandalar dtype başvurusu

Yakaladım, uyarılar, notlar

Ayarlama dtype=objectyukarıdaki uyarıyı susturur, ancak belleği daha verimli hale getirmez, sadece bir şey varsa verimli çalışır.

Ayar dtype=unicodehiçbir şey yapmaz, çünkü numpy için a unicodeolarak temsil edilir object.

Dönüştürücülerin kullanımı

@sparrow, 'foobar'olarak belirtilen bir sütunda karşılaşıldığında pandaların patlamasını önlemek için dönüştürücü kullanımını doğru bir şekilde işaret eder int. Dönüştürücülerin pandalarda kullanım için gerçekten ağır ve verimsiz olduğunu ve son çare olarak kullanılması gerektiğini eklemek istiyorum. Bunun nedeni read_csv işleminin tek bir işlem olmasıdır.

CSV dosyaları satır satır işlenebilir ve böylece pandaların desteklemediği bir dosyayı basitçe parçalara ayırarak ve birden çok işlemi çalıştırarak paralel olarak birden çok dönüştürücü tarafından daha verimli bir şekilde işlenebilir. Ama bu farklı bir hikaye.


6
Yani, a ayarının dtype=objectbellekte daha verimli olmadığı göz önüne alındığında , hatadan kurtulmanın yanı sıra onunla uğraşmak için herhangi bir neden var mı?
zthomas.nc

6
@ zthomas.nc evet, Panda'nın sütunda ne olduğunu test etmesine gerek yok. Teorik olarak yükleme sırasında biraz bellek tasarrufu (ancak yükleme tamamlandıktan sonra hiçbiri) ve teorik olarak bazı işlemci döngülerini kaydetme (disk G /
Ç'nin

5
"Ayrıca, dosyadaki son satırda user_id sütununda" foobar "yazılırsa, yukarıdaki dtype belirtilirse yükleme çökecektir." çökmek yerine bu satırı atmak için kullanılabilecek bazı "zorlama" seçeneği var mı?
serçe

5
@sparrow olabilir, ama son kullandığımda böcek vardı. Pandaların en son sürümünde düzeltilebilir. error_bad_lines=False, warn_bad_lines=Truehile yapmalı. Belgeler sadece C ayrıştırıcısı için geçerli olduğunu söylüyor. Ayrıca, varsayılan ayrıştırıcının Yok olduğunu belirtir, bu da hangisinin varsayılan olduğunu bilmeyi zorlaştırır.
firelynx

5
@nealmcb Veri nrows=100çerçevesini bir argüman olarak okuyabilir ve daha sonra df.dtypesaldığınız dtypes'i görebilirsiniz. Ancak, bu veri türleriyle tüm veri çerçevesini okurken, try/excepthatalı dtype tahminlerini yakalamak için bunu yaptığınızdan emin olun . Veri kirli.
firelynx

50

Deneyin:

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

Panda belgelerine göre:

dtype: Sütunun adını veya dictini yazın -> yazın

Low_memory için, varsayılan olarak doğrudur ve henüz belgelenmemiştir. Bununla ilgili olduğunu düşünmüyorum. Hata mesajı geneldir, bu nedenle low_memory ile uğraşmanıza gerek kalmaz. Umarım bu yardımcı olur ve başka sorunlarınız varsa bana bildirin


1
Ekleme dtype=unicodeüretilen: NameError: name 'unicode' is not defined. Ama unicodetırnak işaretleri koymak ('unicode' gibi) işe yarıyor gibi görünüyor!
sedeh

5
@sedeh dtypes'i python türleri veya olarak belirtebilirsiniz numpy.dtype('unicode'). Dtype seçeneğine bir dize verdiğinizde, numpy.dtype()varsayılan olarak fabrikada yayınlamaya çalışır . Belirtmek 'unicode'aslında hiçbir şey yapmaz, unicodes sadece ortaya çıkar objects. Sen alacakdtype='object'
firelynx

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

Bu sorunu çözmelidir. Bir CSV'den 1.8M satır okurken tam olarak aynı hatayı aldım.


51
Bu hatayı susturur, ancak aslında başka hiçbir şeyi değiştirmez.
Firelynx

2
1.5GB

18

Daha önce belirtildiği gibi, dynpe açıkça belirtilmişse ve bu dtype ile uyumlu olmayan karışık veriler varsa firelynx tarafından belirtildiği gibi yükleme çökecektir. Verilerin hala yüklenebilmesi için, uyumsuz veri türündeki değerleri değiştirmek için geçici bir çözüm olarak böyle bir dönüştürücü kullandım.

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'lık bir dosya ile benzer bir sorun yaşadım. Ayar low_memory=Falsebenim için hile yaptı. Önce basit şeyleri yapın, veri çerçevenizin sistem belleğinizden daha büyük olmadığını kontrol edin, yeniden başlatın, devam etmeden önce RAM'i temizleyin. Hala hatalarla karşılaşıyorsanız, .csvdosyanızın iyi olduğundan emin olmaya değer , Excel'e hızlıca göz atın ve belirgin bir bozulma olmadığından emin olun. Bozuk orijinal veriler hasara yol açabilir ...


1

Büyük bir csv dosyası (6 milyon satır) işlerken benzer bir sorunla karşı karşıyaydım. Üç sorun vardı: 1. dosya garip karakterler (kodlama kullanılarak sabit) içeriyordu 2. veri türü belirtilmedi (dtype özelliği kullanılarak sabit) 3. Yukarıdakileri kullanarak hala olamazdı file_format ile ilgili bir sorunla karşı karşıya dosya adına göre tanımlanır (try .. kullanılarak sabit ..)

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 = FalseBir DataFrame içe aktarırken benim için çalıştı . Benim için işe yarayan değişiklik buydu:

df = pd.read_csv('export4_16.csv',low_memory=False)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.