it-swarm.com.de

So lesen Sie eine 6-GB-CSV-Datei mit Pandas

Ich versuche, eine große CSV-Datei (ca. 6 GB) in Pandas zu lesen, und ich erhalte den folgenden Speicherfehler:

MemoryError                               Traceback (most recent call last)
<ipython-input-58-67a72687871b> in <module>()
----> 1 data=pd.read_csv('aphro.csv',sep=';')

C:\Python27\lib\site-packages\pandas\io\parsers.pyc in parser_f(filepath_or_buffer, sep, dialect, compression, doublequote, escapechar, quotechar, quoting, skipinitialspace, lineterminator, header, index_col, names, prefix, skiprows, skipfooter, skip_footer, na_values, na_fvalues, true_values, false_values, delimiter, converters, dtype, usecols, engine, delim_whitespace, as_recarray, na_filter, compact_ints, use_unsigned, low_memory, buffer_lines, warn_bad_lines, error_bad_lines, keep_default_na, thousands, comment, decimal, parse_dates, keep_date_col, dayfirst, date_parser, memory_map, nrows, iterator, chunksize, verbose, encoding, squeeze, mangle_dupe_cols, tupleize_cols, infer_datetime_format)
    450                     infer_datetime_format=infer_datetime_format)
    451 
--> 452         return _read(filepath_or_buffer, kwds)
    453 
    454     parser_f.__= name

C:\Python27\lib\site-packages\pandas\io\parsers.pyc in _read(filepath_or_buffer, kwds)
    242         return parser
    243 
--> 244     return parser.read()
    245 
    246 _parser_defaults = {

C:\Python27\lib\site-packages\pandas\io\parsers.pyc in read(self, nrows)
    693                 raise ValueError('skip_footer not supported for iteration')
    694 
--> 695         ret = self._engine.read(nrows)
    696 
    697         if self.options.get('as_recarray'):

C:\Python27\lib\site-packages\pandas\io\parsers.pyc in read(self, nrows)
   1137 
   1138         try:
-> 1139             data = self._reader.read(nrows)
   1140         except StopIteration:
   1141             if nrows is None:

C:\Python27\lib\site-packages\pandas\parser.pyd in pandas.parser.TextReader.read (pandas\parser.c:7145)()

C:\Python27\lib\site-packages\pandas\parser.pyd in pandas.parser.TextReader._read_low_memory (pandas\parser.c:7369)()

C:\Python27\lib\site-packages\pandas\parser.pyd in pandas.parser.TextReader._read_rows (pandas\parser.c:8194)()

C:\Python27\lib\site-packages\pandas\parser.pyd in pandas.parser.TextReader._convert_column_data (pandas\parser.c:9402)()

C:\Python27\lib\site-packages\pandas\parser.pyd in pandas.parser.TextReader._convert_tokens (pandas\parser.c:10057)()

C:\Python27\lib\site-packages\pandas\parser.pyd in pandas.parser.TextReader._convert_with_dtype (pandas\parser.c:10361)()

C:\Python27\lib\site-packages\pandas\parser.pyd in pandas.parser._try_int64 (pandas\parser.c:17806)()

MemoryError: 

Hilfe dazu? 

115

Der Fehler zeigt an, dass der Computer nicht über genügend Speicher verfügt, um die gesamte CSV-Datei auf einmal in einen DataFrame einzulesen. Angenommen, Sie benötigen nicht das gesamte Dataset gleichzeitig in Memory. Eine Möglichkeit, das Problem zu vermeiden, besteht darin, CSV in Chunks verarbeiten (durch Angabe des Parameters chunksize):

chunksize = 10 ** 6
for chunk in pd.read_csv(filename, chunksize=chunksize):
    process(chunk)

Der Parameter chucksize gibt die Anzahl der Zeilen pro Block an . (Der letzte Block kann natürlich weniger als chunksize Zeilen enthalten.)

153
unutbu

Chunking sollte nicht immer die erste Anlaufstelle für dieses Problem sein.

1. Ist die Datei aufgrund wiederholter nicht numerischer Daten oder unerwünschter Spalten groß? 

In diesem Fall können Sie manchmal erhebliche Speichereinsparungen durch Einlesen der Spalten als Kategorien und Auswahl der erforderlichen Spalten über den Parameter pd.read_csvusecols feststellen.

2. Erfordert Ihr Workflow das Schneiden, Manipulieren und Exportieren?

In diesem Fall können Sie dask.dataframe verwenden, um Ihre Berechnungen durchzuführen und iterativ zu exportieren. Das Chunking wird von dask, das auch eine Teilmenge der Pandas-API unterstützt, im Hintergrund ausgeführt.

3. Wenn alles andere fehlschlägt, lesen Sie Zeile für Zeile über Chunks.

Chunk via Pandas oder über csv-Bibliothek als letztes Mittel.

38
jpp

Ich ging so vor:

chunks=pd.read_table('aphro.csv',chunksize=1000000,sep=';',\
       names=['lat','long','rf','date','slno'],index_col='slno',\
       header=None,parse_dates=['date'])

df=pd.DataFrame()
%time df=pd.concat(chunk.groupby(['lat','long',chunk['date'].map(lambda x: x.year)])['rf'].agg(['sum']) for chunk in chunks)
29

Für große Daten empfehle ich die Bibliothek "dask" 
z.B: 

# Dataframes implement the Pandas API
import dask.dataframe as dd
df = dd.read_csv('s3://.../2018-*-*.csv')

Die obige Antwort befriedigt das Thema bereits. Wenn Sie alle Daten im Speicher benötigen, besuchen Sie bcolz . Es komprimiert die Daten im Speicher. Ich habe wirklich gute Erfahrungen damit gemacht. Aber es fehlen viele Pandas

Edit: Ich habe Kompressionsraten von etwa 1/10 oder orig. Fehlende wichtige Merkmale waren Aggregate. 

8
PlagTag

Sie können die Daten als Chunks einlesen und jeden Chunk als Pickle speichern. 

import pandas as pd 
import pickle

in_path = "" #Path where the large file is
out_path = "" #Path to save the pickle files to
chunk_size = 400000 #size of chunks relies on your available memory
separator = "~"

reader = pd.read_csv(in_path,sep=separator,chunksize=chunk_size, 
                    low_memory=False)    

i=1
for chunk in reader:
    out_file = out_path + "/data_{}.pkl".format(i)
    with open(out_file, "wb") as f:
        pickle.dump(chunk,f,pickle.HIGHEST_PROTOCOL)
    i+=1

Im nächsten Schritt lesen Sie die Pickles ein und hängen jedes Pickle an Ihren gewünschten Datenrahmen an.

import glob
pickle_path = "" #Same Path as out_path i.e. where the pickle files are

data_p_files=[]
for name in glob.glob(pickle_path + "/data_*.pkl"):
   data_p_files.append(name)


df = pd.DataFrame([])
for i in range(len(data_p_files)):
    df = df.append(pd.read_pickle(data_p_files[i]),ignore_index=True)
4
Humpe

Lösung 1: 

Pandas mit großen Daten verwenden

Lösung 2:

TextFileReader = pd.read_csv(path, chunksize=1000)  # the number of rows per chunk

dfList = []
for df in TextFileReader:
    dfList.append(df)

df = pd.concat(dfList,sort=False)
3
blacksheep

Die Funktion read_csv und read_table ist fast gleich. Sie müssen jedoch das Trennzeichen "," zuweisen, wenn Sie in Ihrem Programm die Funktion read_table verwenden.

def get_from_action_data(fname, chunk_size=100000):
    reader = pd.read_csv(fname, header=0, iterator=True)
    chunks = []
    loop = True
    while loop:
        try:
            chunk = reader.get_chunk(chunk_size)[["user_id", "type"]]
            chunks.append(chunk)
        except StopIteration:
            loop = False
            print("Iteration is stopped")

    df_ac = pd.concat(chunks, ignore_index=True)
2
Tyrion W

Sie können sframe versuchen, das dieselbe Syntax wie Pandas hat, aber Sie können Dateien bearbeiten, die größer als Ihr RAM sind.

2
NunodeSousa

Hier folgt ein Beispiel:

chunkTemp = []
queryTemp = []
query = pd.DataFrame()

for chunk in pd.read_csv(file, header=0, chunksize=<your_chunksize>, iterator=True, low_memory=False):

    #REPLACING BLANK SPACES AT COLUMNS' NAMES FOR SQL OPTIMIZATION
    chunk = chunk.rename(columns = {c: c.replace(' ', '') for c in chunk.columns})

    #YOU CAN EITHER: 
    #1)BUFFER THE CHUNKS IN ORDER TO LOAD YOUR WHOLE DATASET 
    chunkTemp.append(chunk)

    #2)DO YOUR PROCESSING OVER A CHUNK AND STORE THE RESULT OF IT
    query = chunk[chunk[<column_name>].str.startswith(<some_pattern>)]   
    #BUFFERING PROCESSED DATA
    queryTemp.append(query)

#!  NEVER DO pd.concat OR pd.DataFrame() INSIDE A LOOP
print("Database: CONCATENATING CHUNKS INTO A SINGLE DATAFRAME")
chunk = pd.concat(chunkTemp)
print("Database: LOADED")

#CONCATENATING PROCESSED DATA
query = pd.concat(queryTemp)
print(query)
1
jonathask

Wenn Sie Pandas verwenden, lesen Sie eine große Datei in einen Block und geben Sie dann Zeile für Zeile nach. Hier ist, was ich getan habe

import pandas as pd

def chunck_generator(filename, header=False,chunk_size = 10 ** 5):
   for chunk in pd.read_csv(filename,delimiter=',', iterator=True, chunksize=chunk_size, parse_dates=[1] ): 
        yield (chunk)

def _generator( filename, header=False,chunk_size = 10 ** 5):
    chunk = chunck_generator(filename, header=False,chunk_size = 10 ** 5)
    for row in chunk:
        yield row

if __== "__main__":
filename = r'file.csv'
        generator = generator(filename=filename)
        while True:
           print(next(generator))
1
paulg

Zusätzlich zu den obigen Antworten ist d6tstack für diejenigen, die CSV verarbeiten und anschließend in CSV, Parkett oder SQL exportieren möchten, eine gute Option. Sie können mehrere Dateien laden und befasst sich mit Änderungen des Datenschemas (hinzugefügte/entfernte Spalten). Chunked Out-Core-Unterstützung ist bereits eingebaut.

def apply(dfg):
    # do stuff
    return dfg

c = d6tstack.combine_csv.CombinerCSV([bigfile.csv], apply_after_read=apply, sep=',', chunksize=1e6)

# or
c = d6tstack.combine_csv.CombinerCSV(glob.glob('*.csv'), apply_after_read=apply, chunksize=1e6)

# output to various formats, automatically chunked to reduce memory consumption
c.to_csv_combine(filename='out.csv')
c.to_parquet_combine(filename='out.pq')
c.to_psql_combine('postgresql+psycopg2://usr:[email protected]/db', 'tablename') # fast for postgres
c.to_mysql_combine('mysql+mysqlconnector://usr:[email protected]/db', 'tablename') # fast for mysql
c.to_sql_combine('postgresql+psycopg2://usr:[email protected]/db', 'tablename') # slow but flexible
0
citynorman

Für den Fall, dass noch jemand so etwas sucht, habe ich festgestellt, dass diese neue Bibliothek mit dem Namen modin helfen kann. Es verwendet verteiltes Computing, das beim Lesen helfen kann. Hier ist ein Nizza Artikel der seine Funktionalität mit Pandas vergleicht. Es verwendet im Wesentlichen die gleichen Funktionen wie Pandas.

import modin.pandas as pd
pd.read_csv(CSV_FILE_NAME)
0
Jaskaran