Pandy odczytują opcje csv low memory i dtype

Podczas wywoływania

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

Otrzymuję:

/Users/josh/anaconda / envs / py27 / lib / python2. 7/site-packages/pandy / io / parsers.py:1130: DtypeWarning: kolumny (4,5,7,16) mają mieszane typy. Określ typ dtype opcja import lub set low_memory = False.

Dlaczego opcja dtype jest powiązana z low_memory i dlaczego zrobienie jej False pomogłoby w tym problemie?

Author: firelynx, 2014-06-16

10 answers

Przestarzała opcja low_memory

Opcja low_memory nie jest właściwie przestarzała, ale powinna być, ponieważ w rzeczywistości nie robi nic inaczej [source ]

Powodem, dla którego dostajesz to Ostrzeżenie low_memory jest to, że zgadywanie dtypów dla każdej kolumny jest bardzo wymagające dla pamięci. Pandas próbuje określić, jaki typ dtype ustawić, analizując dane w każdej kolumnie.

Dtype zgadywanie (bardzo źle)

Pandy mogą tylko określić, jaki dtype powinna mieć kolumna po przeczytaniu całego pliku. Oznacza to, że nic tak naprawdę nie może być analizowane przed odczytaniem całego pliku, chyba że istnieje ryzyko zmiany typu dtype tej kolumny podczas odczytu ostatniej wartości.

Rozważ przykład jednego pliku, który ma kolumnę o nazwie user_id. Zawiera 10 milionów wierszy, w których user_id to zawsze liczby. Ponieważ pandy nie mogą wiedzieć, że to tylko liczby, prawdopodobnie zachowają je jako oryginalne ciągi znaków, dopóki nie przeczytają całego pliku.

Określanie dtypów (powinno zawsze bądź gotowy)

Dodanie

dtype={'user_id': int}

Do pd.read_csv() wywołanie spowoduje, że pandy będą wiedzieć, kiedy zacznie odczytywać Plik, że są to tylko liczby całkowite.

Warto również zauważyć, że jeśli ostatnia linia w pliku będzie miała "foobar" zapisaną w kolumnie user_id, Ładowanie ulegnie awarii, jeśli podany zostanie powyższy Typ dtype.

Przykład uszkodzonych danych, które ulegają uszkodzeniu, gdy zdefiniowane są dtypy

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'

Dtypy są zazwyczaj numpy, przeczytaj więcej o nich proszę.: http://docs.scipy.org/doc/numpy/reference/generated/numpy.dtype.html

Jakie dtypy istnieją?

Mamy dostęp do numpy dtypes: float, int, bool, timedelta64[NS] i datetime64 [NS]. Zauważ, że dtypy daty/czasu numpy są świadome strefy czasowej , a nie.

Pandy rozszerza ten zestaw dtyp o własne:

'datetime64 [ns,]', który jest znacznikiem czasu świadomym strefy czasowej.

'kategoria', która jest w zasadzie enum (ciągi reprezentowane przez klucze całkowite do zapisania

'period []' nie należy mylić z timedelta, obiekty te są faktycznie zakotwiczone w określonych okresach czasu

'Sparse', ' Sparse[int]',' Sparse[float] ' jest dla danych o ograniczonej ilości danych lub 'Data that has a lot of holes in it' zamiast zapisywania NaN lub None w ramce danych pomija obiekty, oszczędzając miejsce.

'interwał' jest sam w sobie tematem, ale jego głównym zastosowaniem jest indeksowanie. Zobacz więcej tutaj

'Int8', 'Int16', 'Int32', 'Int64', 'UInt8', 'UInt16', 'UInt32', 'UInt64' to wszystkie liczby całkowite specyficzne dla pand, które są nullable, w przeciwieństwie do wariantu numpy.

'string' jest specyficznym typem dtype do pracy z danymi string i daje dostęp do atrybutu .str w serii.

'boolean' jest jak numpy 'bool', ale obsługuje również brakujące dane.

Przeczytaj cały odnośnik tutaj:

Pandy dtype reference

Gotchas, caveats, notes

Ustawienie dtype=object uciszy powyżej Ostrzeżenie, ale nie sprawi, że będzie bardziej wydajna pamięć, tylko proces wydajny, jeśli w ogóle.

Ustawienie dtype=unicode nic nie da, ponieważ dla numpy, {[10] } jest reprezentowane jako object.

Wykorzystanie konwerterów

@sparrow poprawnie zwraca uwagę na użycie konwerterów, aby uniknąć wybuchu pand podczas napotkania 'foobar' w kolumnie określonej jako int. Chciałbym dodać, że konwertery są naprawdę ciężkie i nieefektywne w użyciu w pandach i powinny być używane jako ostatni Ośrodek wypoczynkowy. Dzieje się tak, ponieważ proces read_csv jest pojedynczym procesem.

Pliki CSV mogą być przetwarzane linia po linii, a tym samym mogą być przetwarzane przez wiele konwerterów równolegle bardziej efektywnie, po prostu przecinając plik na segmenty i uruchamiając wiele procesów, czego pandy nie obsługują. Ale to inna historia.

 512
Author: firelynx,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-20 09:12:55

Try:

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

Według dokumentacji pandy:

Dtype: Nazwa typu lub dict kolumny - > typ

Jeśli chodzi o low_memory, jest to prawda domyślnie i nie jest jeszcze udokumentowane. Nie sądzę, żeby to miało znaczenie. Komunikat o błędzie jest ogólny, więc nie powinieneś i tak mieszać z low_memory. Mam nadzieję, że to pomoże i daj mi znać, jeśli masz dalsze problemy

 58
Author: hd1,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-02 23:39:17
df = pd.read_csv('somefile.csv', low_memory=False)
To powinno rozwiązać problem. Mam dokładnie ten sam błąd, podczas odczytu wierszy 1.8 M Z pliku CSV.
 47
Author: Neal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-13 08:32:12

Jak wspomniano wcześniej przez firelynx jeśli dtype jest jawnie określony i istnieją mieszane DANE, które nie są zgodne z tym dtype, Ładowanie ulegnie awarii. Użyłem takiego konwertera jako obejścia zmiany wartości z niezgodnym typem danych, aby dane mogły być nadal ładowane.

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})
 18
Author: sparrow,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-02 18:17:01

To działało dla mnie z low_memory = False Podczas importowania ramki danych. To jest cała zmiana, która zadziałała dla mnie:

df = pd.read_csv('export4_16.csv',low_memory=False)
 4
Author: Rajat Saxena,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-04-17 14:53:43

Miałem podobny problem z plikiem ~400MB. Ustawienie low_memory=False załatwiło mi sprawę. Najpierw zrób proste rzeczy, sprawdziłbym, czy twoja ramka danych nie jest większa niż pamięć systemowa, zrestartuj, Wyczyść RAM przed kontynuowaniem. Jeśli nadal występują błędy, warto upewnić się, że plik .csv jest w porządku, zajrzyj szybko do programu Excel i upewnij się, że nie ma oczywistego uszkodzenia. Uszkodzone oryginalne dane mogą siać spustoszenie...

 2
Author: Dr Nigel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-26 06:53:27

Miałem do czynienia z podobnym problemem podczas przetwarzania ogromnego pliku csv (6 milionów wierszy). Miałem trzy problemy:

  1. Plik zawierał dziwne znaki (naprawione za pomocą kodowania)
  2. typ danych nie został określony (naprawiony przy użyciu właściwości dtype)
  3. korzystając z powyższego, nadal napotkałem problem związany z formatem pliku, którego nie można było zdefiniować na podstawie nazwy pliku (Naprawiono za pomocą try .. z wyjątkiem..)
    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'] = ''
 2
Author: Wim Folkerts,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-11-26 00:02:33

Czasami, gdy Wszystko inne zawodzi, po prostu chcesz powiedzieć Pandzie, żeby się o tym zamknęła:

# Ignore DtypeWarnings from pandas' read_csv                                                                                                                                                                                            
warnings.filterwarnings('ignore', message="^Columns.*")
 1
Author: technomage,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-11-25 23:59:45

Zgodnie z dokumentacją pandy , określając low_memory=False tak długo, jak engine='c' (która jest domyślna) jest rozsądnym rozwiązaniem tego problemu.

Jeśli low_memory=False, to najpierw zostaną wczytane całe kolumny, a następnie określone odpowiednie typy. Na przykład kolumna będzie przechowywana jako obiekty (ciągi znaków) w razie potrzeby do zachowania informacji.

If low_memory=True (domyślne), then pandas wczytuje dane w kawałkach wierszy, a następnie dołącza je razem. Potem kilka kolumn może wyglądać jak kawałki liczb całkowitych i ciągów wymieszanych, w zależności od tego, czy podczas tego fragmentu pandy napotkały coś, czego nie można było rzucić na liczbę całkowitą (powiedzmy). To może powodować problemy później. Ostrzeżenie mówi ci, że zdarzyło się to przynajmniej raz w czytaniu, więc powinieneś być ostrożny. Ustawienie low_memory=False spowoduje użycie większej ilości pamięci, ale pozwoli uniknąć problemu.

Osobiście uważam, że low_memory=True jest złą wartością domyślną, ale pracuję w obszarze, który używa o wiele więcej małych zbiorów danych niż dużych i tak wygoda jest ważniejsza niż wydajność.

Poniższy kod ilustruje przykład, w którym low_memory=True jest ustawiona, a kolumna zawiera typy mieszane. To buduje odpowiedź przez @ firelynx

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

# make a big csv data file, following earlier approach by @firelynx
csvdata = """1,Alice
2,Bob
3,Caesar
"""

# we have to replicate the "integer column" user_id many many times to get
# pd.read_csv to actually chunk read. otherwise it just reads 
# the whole thing in one chunk, because it's faster, and we don't get any 
# "mixed dtype" issue. the 100000 below was chosen by experimentation.
csvdatafull = ""
for i in range(100000):
    csvdatafull = csvdatafull + csvdata
csvdatafull =  csvdatafull + "foobar,Cthlulu\n"
csvdatafull = "user_id,username\n" + csvdatafull

sio = StringIO(csvdatafull)
# the following line gives me the warning:
    # C:\Users\rdisa\anaconda3\lib\site-packages\IPython\core\interactiveshell.py:3072: DtypeWarning: Columns (0) have mixed types.Specify dtype option on import or set low_memory=False.
    # interactivity=interactivity, compiler=compiler, result=result)
# but it does not always give me the warning, so i guess the internal workings of read_csv depend on background factors
x = pd.read_csv(sio, low_memory=True) #, dtype={"user_id": int, "username": "string"})

x.dtypes
# this gives:
# Out[69]: 
# user_id     object
# username    object
# dtype: object

type(x['user_id'].iloc[0]) # int
type(x['user_id'].iloc[1]) # int
type(x['user_id'].iloc[2]) # int
type(x['user_id'].iloc[10000]) # int
type(x['user_id'].iloc[299999]) # str !!!! (even though it's a number! so this chunk must have been read in as strings)
type(x['user_id'].iloc[300000]) # str !!!!!

Na marginesie: aby podać przykład, w którym jest to problem (i gdzie po raz pierwszy napotkałem to jako poważny problem), wyobraź sobie, że uruchomiłeś pd.read_csv() na pliku, a następnie chciałeś zrzucić duplikaty na podstawie identyfikatora. Powiedzmy, że identyfikator jest czasami liczbowy, czasami Łańcuchowy. / Align = "left" / 81287", innym może być "97324-32". Mimo to są to unikalne identyfikatory.

Z low_memory=True, pandy mogą czytać w kolumnie Identyfikator w następujący sposób:

81287
81287
81287
81287
81287
"81287"
"81287"
"81287"
"81287"
"97324-32"
"97324-32"
"97324-32"
"97324-32"
"97324-32"

Tylko dlatego, że kawałki rzeczy i tak, czasami identyfikator 81287 jest liczbą, czasami ciągiem znaków. Kiedy próbuję zrzucić duplikaty na podstawie tego, cóż,

81287 == "81287"
Out[98]: False
 0
Author: Richard DiSalvo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-07-19 01:36:30

Jak mówi błąd, należy określić typy danych przy użyciu metody read_csv(). Więc powinieneś napisać

file = pd.read_csv('example.csv', dtype='unicode')
 0
Author: Mahmoud Ragab,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-08-15 17:13:42