Pandas read csv memory error

I am trying to do something fairly simple, reading a large csv file into a pandas dataframe. data = pandas.read_csv(filepath, header = 0, sep = DELIMITER,skiprows = 2) The code either fails with a

I am trying to do something fairly simple, reading a large csv file into a pandas dataframe.

data = pandas.read_csv(filepath, header = 0, sep = DELIMITER,skiprows = 2)

The code either fails with a MemoryError, or just never finishes.

Mem usage in the task manager stopped at 506 Mb and after 5 minutes of no change and no CPU activity in the process I stopped it.

I am using pandas version 0.11.0.

I am aware that there used to be a memory problem with the file parser, but according to http://wesmckinney.com/blog/?p=543 this should have been fixed.

The file I am trying to read is 366 Mb, the code above works if I cut the file down to something short (25 Mb).

It has also happened that I get a pop up telling me that it can’t write to address 0x1e0baf93…

Stacktrace:

Traceback (most recent call last):
  File "F:QA ALMPythonnew WIM datanew WIM datanew_WIM_data.py", line 25, in
 <module>
    wimdata = pandas.read_csv(filepath, header = 0, sep = DELIMITER,skiprows = 2
)
  File "C:Program FilesPythonAnacondalibsite-packagespandasioparsers.py"
, line 401, in parser_f
    return _read(filepath_or_buffer, kwds)
  File "C:Program FilesPythonAnacondalibsite-packagespandasioparsers.py"
, line 216, in _read
    return parser.read()
  File "C:Program FilesPythonAnacondalibsite-packagespandasioparsers.py"
, line 643, in read
    df = DataFrame(col_dict, columns=columns, index=index)
  File "C:Program FilesPythonAnacondalibsite-packagespandascoreframe.py"
, line 394, in __init__
    mgr = self._init_dict(data, index, columns, dtype=dtype)
  File "C:Program FilesPythonAnacondalibsite-packagespandascoreframe.py"
, line 525, in _init_dict
    dtype=dtype)
  File "C:Program FilesPythonAnacondalibsite-packagespandascoreframe.py"
, line 5338, in _arrays_to_mgr
    return create_block_manager_from_arrays(arrays, arr_names, axes)
  File "C:Program FilesPythonAnacondalibsite-packagespandascoreinternals
.py", line 1820, in create_block_manager_from_arrays
    blocks = form_blocks(arrays, names, axes)
  File "C:Program FilesPythonAnacondalibsite-packagespandascoreinternals
.py", line 1872, in form_blocks
    float_blocks = _multi_blockify(float_items, items)
  File "C:Program FilesPythonAnacondalibsite-packagespandascoreinternals
.py", line 1930, in _multi_blockify
    block_items, values = _stack_arrays(list(tup_block), ref_items, dtype)
  File "C:Program FilesPythonAnacondalibsite-packagespandascoreinternals
.py", line 1962, in _stack_arrays
    stacked = np.empty(shape, dtype=dtype)
MemoryError
Press any key to continue . . .

A bit of background — I am trying to convince people that Python can do the same as R. For this I am trying to replicate an R script that does

data <- read.table(paste(INPUTDIR,config[i,]$TOEXTRACT,sep=""), HASHEADER, DELIMITER,skip=2,fill=TRUE)

R not only manages to read the above file just fine, it even reads several of these files in a for loop (and then does some stuff with the data). If Python does have a problem with files of that size I might be fighting a loosing battle…

  1. What is the Memory Error in Pandas
  2. How to Avoid the Memory Error in Pandas

Memory Error in Pandas

This tutorial explores the concept of memory error in Pandas.

What is the Memory Error in Pandas

While working with Pandas, an analyst might encounter multiple errors that the code interpreter throws. These errors are widely ranged and would help us better investigate the issue.

In this tutorial, we aim to better understand the memory error thrown by Pandas, the reason behind it throwing that error and the potential ways by which this error can be resolved.

Firstly, let us understand what this error means. A memory error means that there is not enough memory on the server or the database you’re trying to access to complete the operation or task you wish to perform.

This error is generally associated with files and CSV data that have the order of hundreds of gigabytes. It is important to understand what causes this error and avoid such an error to have more data storage.

Solving this error can also help develop an efficient and thorough database with proper rule management.

Assuming we’re trying to fetch data from a CSV file with more than 1000 gigabytes of data, we will naturally face the memory error discussed above. This error can be illustrated below.

MemoryError
Press any key to continue . . .

There is a method by which we can avoid this memory error potentially. However, before we do that, let us create a dummy data frame to work with.

We will call this data frame dat1. Let us create this data frame using the following code.

import pandas as pd
dat1 = pd.DataFrame(pd.np.random.choice(['1.0', '0.6666667', '150000.1'],(100000, 10)))

The query creates 10 columns indexed from 0 to 9 and 100000 values. To view the entries in the data, we use the following code.

The above code gives the following output.

               0          1          2  ...          7          8          9
0            1.0        1.0        1.0  ...   150000.1  0.6666667  0.6666667
1      0.6666667  0.6666667        1.0  ...  0.6666667   150000.1  0.6666667
2            1.0        1.0   150000.1  ...   150000.1        1.0   150000.1
3       150000.1  0.6666667  0.6666667  ...        1.0   150000.1        1.0
4       150000.1  0.6666667   150000.1  ...   150000.1  0.6666667  0.6666667
...          ...        ...        ...  ...        ...        ...        ...
99995   150000.1   150000.1        1.0  ...   150000.1        1.0  0.6666667
99996        1.0        1.0   150000.1  ...  0.6666667  0.6666667   150000.1
99997   150000.1   150000.1        1.0  ...  0.6666667   150000.1  0.6666667
99998        1.0  0.6666667  0.6666667  ...  0.6666667        1.0   150000.1
99999        1.0  0.6666667   150000.1  ...        1.0   150000.1        1.0

[100000 rows x 10 columns]

How to Avoid the Memory Error in Pandas

Now let us see the total space that this data frame occupies using the following code.

resource.getrusage(resource.RUSAGE_SELF).ru_maxrss

The code gives the following output.

To avoid spending so much space on just a single data frame, let us do this by specifying exactly the data type we’re dealing with.

This helps us reduce the total memory required as lesser space is required to understand the type of data, and more space can be allotted to the actual data under consideration.

We can do this using the following query.

df = pd.DataFrame(pd.np.random.choice([1.0, 0.6666667, 150000.1],(100000, 10)))
resource.getrusage(resource.RUSAGE_SELF).ru_maxrss

The output of the code is below.

Since we have specified the data type as int here by not assigning strings, we have successfully reduced the memory space required for our data.

Thus, we have learned the meaning, cause, and potential solution with this tutorial regarding the memory error thrown in Pandas.

I am trying to do something fairly simple, reading a large csv file into a pandas dataframe.

data = pandas.read_csv(filepath, header = 0, sep = DELIMITER,skiprows = 2)

The code either fails with a MemoryError, or just never finishes.

Mem usage in the task manager stopped at 506 Mb and after 5 minutes of no change and no CPU activity in the process I stopped it.

I am using pandas version 0.11.0.

I am aware that there used to be a memory problem with the file parser, but according to http://wesmckinney.com/blog/?p=543 this should have been fixed.

The file I am trying to read is 366 Mb, the code above works if I cut the file down to something short (25 Mb).

It has also happened that I get a pop up telling me that it can’t write to address 0x1e0baf93…

Stacktrace:

Traceback (most recent call last):
  File "F:QA ALMPythonnew WIM datanew WIM datanew_WIM_data.py", line 25, in
 <module>
    wimdata = pandas.read_csv(filepath, header = 0, sep = DELIMITER,skiprows = 2
)
  File "C:Program FilesPythonAnacondalibsite-packagespandasioparsers.py"
, line 401, in parser_f
    return _read(filepath_or_buffer, kwds)
  File "C:Program FilesPythonAnacondalibsite-packagespandasioparsers.py"
, line 216, in _read
    return parser.read()
  File "C:Program FilesPythonAnacondalibsite-packagespandasioparsers.py"
, line 643, in read
    df = DataFrame(col_dict, columns=columns, index=index)
  File "C:Program FilesPythonAnacondalibsite-packagespandascoreframe.py"
, line 394, in __init__
    mgr = self._init_dict(data, index, columns, dtype=dtype)
  File "C:Program FilesPythonAnacondalibsite-packagespandascoreframe.py"
, line 525, in _init_dict
    dtype=dtype)
  File "C:Program FilesPythonAnacondalibsite-packagespandascoreframe.py"
, line 5338, in _arrays_to_mgr
    return create_block_manager_from_arrays(arrays, arr_names, axes)
  File "C:Program FilesPythonAnacondalibsite-packagespandascoreinternals
.py", line 1820, in create_block_manager_from_arrays
    blocks = form_blocks(arrays, names, axes)
  File "C:Program FilesPythonAnacondalibsite-packagespandascoreinternals
.py", line 1872, in form_blocks
    float_blocks = _multi_blockify(float_items, items)
  File "C:Program FilesPythonAnacondalibsite-packagespandascoreinternals
.py", line 1930, in _multi_blockify
    block_items, values = _stack_arrays(list(tup_block), ref_items, dtype)
  File "C:Program FilesPythonAnacondalibsite-packagespandascoreinternals
.py", line 1962, in _stack_arrays
    stacked = np.empty(shape, dtype=dtype)
MemoryError
Press any key to continue . . .

A bit of background — I am trying to convince people that Python can do the same as R. For this I am trying to replicate an R script that does

data <- read.table(paste(INPUTDIR,config[i,]$TOEXTRACT,sep=""), HASHEADER, DELIMITER,skip=2,fill=TRUE)

R not only manages to read the above file just fine, it even reads several of these files in a for loop (and then does some stuff with the data). If Python does have a problem with files of that size I might be fighting a loosing battle…

I have been implementing a DecisionTreeRegressor model in Anaconda environment with a data set sourced from a 20 million row, 12-dimensional CSV file. I could get the chunks off of the data set with chunksize set to 500,000 rows and process the computation of the R-Squared score on the training/test split data sets in each iteration of 500,000 rows till iteration #20.

sklearn.__version__: 0.19.0 
pandas.__version__: 0.20.3 
numpy.__version__: 1.13.1

The GridSearchCV() instance uses parameter grid with parameter max_depth set to values [4, 6].

I then see memory errors in numpy module with the Anaconda Python interpreter throwing an exception.

This is the exception after iteration #20:

Score for model trained on Test Dataset:  -0.000287864727209
Best Parameters:  {'max_depth': 4} 
Best Cross-Validation Accuracy:  -0.00037759422675 

Traceback (most recent call last):

  File "<ipython-input-1-a28a1b71d60d>", line 1, in <module>
    runfile('C:/Kal/Stat-Work/Stat-Code/SciKit/Final/DecisionTreeRegression-MaximumDepthFour.py', wdir='C:/Kal/Stat-Work/Stat-Code/SciKit/Final')

  File "C:UsersbkalahasAppDataLocalContinuumanaconda3libsite-packagesspyderutilssitesitecustomize.py", line 710, in runfile
    execfile(filename, namespace)

  File "C:UsersbkalahasAppDataLocalContinuumanaconda3libsite-packagesspyderutilssitesitecustomize.py", line 101, in execfile
    exec(compile(f.read(), filename, 'exec'), namespace)

  File "C:/Kal/Stat-Work/Stat-Code/SciKit/Final/DecisionTreeRegression-MaximumDepthFour.py", line 21, in <module>
    for piece in chunker:

  File "C:UsersbkalahasAppDataLocalContinuumanaconda3libsite-packagespandasioparsers.py", line 978, in __next__
    return self.get_chunk()

  File "C:UsersbkalahasAppDataLocalContinuumanaconda3libsite-packagespandasioparsers.py", line 1042, in get_chunk
    return self.read(nrows=size)

  File "C:UsersbkalahasAppDataLocalContinuumanaconda3libsite-packagespandasioparsers.py", line 1023, in read
    df = DataFrame(col_dict, columns=columns, index=index)

  File "C:UsersbkalahasAppDataLocalContinuumanaconda3libsite-packagespandascoreframe.py", line 275, in __init__
    mgr = self._init_dict(data, index, columns, dtype=dtype)

  File "C:UsersbkalahasAppDataLocalContinuumanaconda3libsite-packagespandascoreframe.py", line 411, in _init_dict
    return _arrays_to_mgr(arrays, data_names, index, columns, dtype=dtype)

  File "C:UsersbkalahasAppDataLocalContinuumanaconda3libsite-packagespandascoreframe.py", line 5506, in _arrays_to_mgr
    return create_block_manager_from_arrays(arrays, arr_names, axes)

  File "C:UsersbkalahasAppDataLocalContinuumanaconda3libsite-packagespandascoreinternals.py", line 4309, in create_block_manager_from_arrays
    blocks = form_blocks(arrays, names, axes)

  File "C:UsersbkalahasAppDataLocalContinuumanaconda3libsite-packagespandascoreinternals.py", line 4381, in form_blocks
    int_blocks = _multi_blockify(int_items)

  File "C:UsersbkalahasAppDataLocalContinuumanaconda3libsite-packagespandascoreinternals.py", line 4450, in _multi_blockify
    values, placement = _stack_arrays(list(tup_block), dtype)

  File "C:UsersbkalahasAppDataLocalContinuumanaconda3libsite-packagespandascoreinternals.py", line 4493, in _stack_arrays
    stacked = np.empty(shape, dtype=dtype)

MemoryError

This is the code:

# Read the dataset into a DataFrame from the Test Regression CSV file. 
chunker = pd.read_csv('C:/Kal/Stat-Work/Stat-Code/SciKit/Test_Data_Set_Regression.csv',
             names=['ROW', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'RT'],
             chunksize=500000, low_memory=False)

for piece in chunker:
    # Create Training and Test Datasets. 
    X_train, X_test, y_train, y_test = train_test_split(
        piece[['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J']], piece['RT'], random_state=0)

    param_grid = {
                 'max_depth': [4, 6]
                 }

    # Instantiate the GridSearchCV class with the model DecisionTreeRegressor, the parameter
    # grid to search param_grid, and the cross-validation strategy we want to use, 
    # say 5 fold (stratified) cross-validation.
    grid_search = GridSearchCV(DecisionTreeRegressor(), param_grid, cv=5)

    # Call fit method to run cross-validation for each combination
    # of parameters we specified in param_grid
    grid_search.fit(X_train, y_train)

    # Print the best_score, best_parameters and the test_score.
    print("Score for model trained on whole Training Dataset: ", grid_search.score(X_train, y_train))

    # Evaluate the generalization performance by calling score method on the Test Dataset.
    print("Score for model trained on Test Dataset: ", grid_search.score(X_test, y_test))
    print("Best Parameters: ", grid_search.best_params_)
    print("Best Cross-Validation Accuracy: ", grid_search.best_score_)

Questions:

  1. Please point to ways to overcome the Python memory error
    exception.
  2. What is the best way to implement a DecisionTreeRegressor model on a
    cluster of 4 16-GB RAM, 2.5-GHz CPU machines (linux or windows)? I
    see memory errors with scale even with DecisionTreeRegressor model.
    SVM model does not even compute fully beyond 20,000 rows in a chunk
    with hung CPUs being seen by the Python interpreter. But, it is
    known that SVM is computationally tedious. Is there a way around
    such memory errors for DecisionTree and Ensemble models when
    combined with Pandas? Pandas is our memory data analytic engine.

The dataset is particularly huge (actual total of 100 million rows in source database as produced almost everyday). Using cross validation against the entire 100 million row dataset is computationally onerous.

I have come up with this Bagging-like model where the dataset is broken into samples of 500,000 rows each and the MSE is computed for each sample. The goal is to compute the averaged out MSE across all samples.

This question is important since it deals with scale which is an everyday computational problem in ML algorithms. I would also appreciate critical answers on various aspects of my code above versus down votes without reason. Thank you.

Я пытаюсь сделать что-то довольно простое, читая большой файл csv в фреймворк pandas.

data = pandas.read_csv(filepath, header = 0, sep = DELIMITER,skiprows = 2)

Код либо терпит неудачу с MemoryError, либо просто не заканчивается.

Использование Mem в диспетчере задач остановилось на 506 Мбайт, и после 5 минут без изменений и активности процессора в этом процессе я его остановил.

Я использую pandas версию 0.11.0.

Мне известно, что с файловым парсером была проблема с памятью, но в соответствии с http://wesmckinney.com/blog/?p=543 это должно было быть исправлена.

Файл, который я пытаюсь прочитать, составляет 366 Мб, код выше работает, если я вырезал файл до чего-то короткого (25 Мб).

Также случилось, что я получаю всплывающее сообщение о том, что он не может написать адрес 0x1e0baf93…

StackTrace:

Traceback (most recent call last):
  File "F:QA ALMPythonnew WIM datanew WIM datanew_WIM_data.py", line 25, in
 <module>
    wimdata = pandas.read_csv(filepath, header = 0, sep = DELIMITER,skiprows = 2
)
  File "C:Program FilesPythonAnacondalibsite-packagespandasioparsers.py"
, line 401, in parser_f
    return _read(filepath_or_buffer, kwds)
  File "C:Program FilesPythonAnacondalibsite-packagespandasioparsers.py"
, line 216, in _read
    return parser.read()
  File "C:Program FilesPythonAnacondalibsite-packagespandasioparsers.py"
, line 643, in read
    df = DataFrame(col_dict, columns=columns, index=index)
  File "C:Program FilesPythonAnacondalibsite-packagespandascoreframe.py"
, line 394, in __init__
    mgr = self._init_dict(data, index, columns, dtype=dtype)
  File "C:Program FilesPythonAnacondalibsite-packagespandascoreframe.py"
, line 525, in _init_dict
    dtype=dtype)
  File "C:Program FilesPythonAnacondalibsite-packagespandascoreframe.py"
, line 5338, in _arrays_to_mgr
    return create_block_manager_from_arrays(arrays, arr_names, axes)
  File "C:Program FilesPythonAnacondalibsite-packagespandascoreinternals
.py", line 1820, in create_block_manager_from_arrays
    blocks = form_blocks(arrays, names, axes)
  File "C:Program FilesPythonAnacondalibsite-packagespandascoreinternals
.py", line 1872, in form_blocks
    float_blocks = _multi_blockify(float_items, items)
  File "C:Program FilesPythonAnacondalibsite-packagespandascoreinternals
.py", line 1930, in _multi_blockify
    block_items, values = _stack_arrays(list(tup_block), ref_items, dtype)
  File "C:Program FilesPythonAnacondalibsite-packagespandascoreinternals
.py", line 1962, in _stack_arrays
    stacked = np.empty(shape, dtype=dtype)
MemoryError
Press any key to continue . . .

Немного фона — я пытаюсь убедить людей в том, что Python может делать то же самое, что и R. Для этого я пытаюсь реплицировать R script, который делает

data <- read.table(paste(INPUTDIR,config[i,]$TOEXTRACT,sep=""), HASHEADER, DELIMITER,skip=2,fill=TRUE)

R не только умеет читать этот файл просто отлично, он даже считывает несколько из этих файлов в цикле for (а затем делает некоторые вещи с данными). Если у Python есть проблема с файлами такого размера, я могу бороться с проигранным сражением…

Работа с данными в pandas, когда их размер не превышает пары гигабайт, проблем не вызывает. Но когда они достигают десятков гигабайт, то обрабатывать их на обычном компьютере становится сложно. Нужно или уменьшать размер датасета или работать с данными, разбитыми на chunk, что долго и не всегда удобно.

Например, в работе при анализе операций клиентов и брокеров на финансовых рынках или транзакций по картам, для выявления мошеннических действий, когда количество таких операций составляет десятки и сотни миллионов, мы получаем долгие часы расчётов или скверное настроение, когда видим сбой вычислений из-за нехватки памяти после многих часов ожидания.

Есть другие инструменты, например, Spark, которые могут обрабатывать большие наборы данных, но для полного использования их возможностей обычно требуется более дорогое оборудование. И обычно их функционал беднее, чем у pandas.

Чтобы не менять инструмент, но при этом реализовать его использование с большими объёмами информации, мы использовали некоторые приёмы.

На первом шаге нам следует определить текущий объём памяти, который занимает датасет.

Если с числовыми значениями всё более или менее очевидно, то с объектами и строками всё запутанней. Pandas загружает в строковые столбцы как object type по умолчанию.

Чтобы заставить Pandas проверять память для каждого связанного строкового значения и возвращать истинный объем памяти, нам нужно установить параметр memory_usage в значение «deep» при вызове DataFrame.info().

df.info(memory_usage=’deep’)

Также мы можем использовать метод memory_usage ()

print(df.memory_usage(deep=True))
obj_cols = df.select_dtypes(include=[‘object’])
obj_cols_mem = obj_cols.memory_usage(deep=True)
print(obj_cols_mem)
obj_cols_sum = obj_cols_mem.sum()/1048576
print(obj_cols_sum)

Для того, чтобы подобрать нужный тип для числовых данных нужно понимать пограничные значения каждого типа и подтипа.

Используем numpy.класс iinfo для проверки минимальных и максимальных значений для каждого целочисленного подтипа:

import numpy as np
int_types = [«int8», «int16», «int32», «int64»]
for it in int_types:
print(np.iinfo(it))

Например, определим максимальное и минимальное значение типа:

print(np.iinfo(«int8»).min)
print(np.iinfo(«int8»).max)

Теперь можно использовать такой алгоритм для поиска типа данных, который потребует наименьших затрат памяти.

col_max = df[‘value’].max()
col_min = df[‘value’].min()

if col_max < np.iinfo(«int8»).max and col_min > np.iinfo(«int8»).min:
df[‘value’] = df[‘value’].astype(«int8»)
elif col_max < np.iinfo(«int16»).max and col_min > np.iinfo(«int16»).min:
df[‘value’] df[‘value’].astype(«int16»)
elif col_max < np.iinfo(«int32»).max and col_min > np.iinfo(«int32»).min:
df[‘value’] = df[‘value’].astype(«int32»)
elif col_max < np.iinfo(«int64»).max and col_min > np.iinfo(«int64»).min:
df[‘value’] = df[‘value’].astype(«int64»)
print(df[‘value’].dtype)
print( df[‘value’]dd.memory_usage(deep=True))

Но данный алгоритм не эффективен для типа float.

Чтобы помочь найти наиболее эффективный тип пространства для столбца, мы можем использовать функцию pandas.to_numeric () как для float так и для integer, не забывая указать downcast=.

float_cols = df.select_dtypes(include=[‘float’])
for col in float_cols.columns:
df[col] = pd.to_numeric(df[col], downcast=’float’)
print(moma.select_dtypes(include=[‘float’]).dtypes)

Некоторые столбцы object type могут являться датами, при этом тип datetime занимает меньше памяти. Мы используем функцию pandas.to_datetime() для преобразования столбца в тип datetime.

df[«settledate»] = pd.to_datetime(df[«settledate»])
print(df[«settledate»].memory_usage(deep=True))

Начиная с версии 0,15 в Pandas ввели категориальный тип. Тип категории использует целочисленные значения для представления значений в столбце. Pandas использует отдельный словарь, который сопоставляет целочисленные значения с необработанными.

Если в категориальном столбце менее 50% уникальных значений (в противном случае выигрыша в памяти не будет), то его смело можно перевести в данный тип. Но следует учесть, что с данным типом нельзя выполнять вычисления или использовать такие методы, как min () и max ().

obj_cols = df.select_dtypes(include=[‘object’])
for col in obj_cols.columns:
num_unique_values = len(df[col].unique())
num_total_values = len(df[col])
if num_unique_values / num_total_values < 0.5:
df[col] = df[col].astype(‘category’)

print(df.info(memory_usage=’deep’))

Из всего, что мы описали выше, были случаи, когда преобразовывался уже готовый датасет. При загрузке данных мы также можем указать оптимальные типы столбцов при чтении набора данных. И тогда мы имеем на ПК уже готовый файл нужного размера, с которым сразу начинаем работать.

Pandas.read_csv() имеет несколько различных параметров, которые позволяют это сделать. Параметр dtype принимает словарь, содержащий имена столбцов (string) в качестве ключей и объекты типа NumPy в качестве значений.

import numpy as np
col_types = {«id»: np.int32}
df = pd.read_csv(‘data.csv’, dtypes=col_types)

Параметр parse_dates принимает список строк, содержащих имена столбцов, которые мы хотим разобрать как значения datetime.

df = pd.read_csv(‘data.csv’, parse_dates=[«StartDate», «EndDate»])

Используя параметр usecols, можно указать, какие столбцы мы хотим включить в исследуемые данные.

df = pd.read_csv(‘data.csv’, usecols=[«Price», «Value», “Clientcode”])

keep_cols = [
‘Price ‘, ‘ Value ‘, ‘ Clientcode ‘,
‘Datetradetime’, ‘Profit’]
df = pd.read_csv(«data.csv», parse

Резюмируем сказанное выше.

Для оптимизации размера, исследуемого датасета, вы можете использовать следующий алгоритм, который уже применяли мы.

  • Для всех столбцов, имеющих object type, попробуйте присвоить этим столбцам нужный тип. Как уже говорилось, по умолчанию Pandas считывает числовые столбцы как float64. Используйте pd.to_numeric чтобы сменить c float64 на 32 или 16, если это возможно.
  • Устраните nan и используйте dtypes.
  • Устраните или замените недостающие данные перед использованием pd.read_csv. Сделайте пропущенные значения -1 или 0 или что-то, что Pandas не интерпретирует как «nan». Почему? Потому что, если столбец содержит nan, Pandas автоматически делает переменную типом данных, который занимает больше памяти.
  • pd.read_csv часто назначает типы данных, которые занимают больше памяти, чем обычно, например, используя float64, когда float16 достаточно. Чтобы устранить эту проблему, можно явно объявить тип данных (и импортировать только необходимые переменные):

dtypes = {«id» : np.int32 , «operation_year» : np.int16 , «amount» : np.int8 , «contract_year» : np.int16 , «value» : np.int8}
vars = dtypes.keys()
dfp = pd.read_csv(path + «operations.csv», usecols = vars, dtype = dtypes, sep = «;», index_col=»id»)

  • Наконец, об этом мы ещё не говорили, но будет хорошим тоном сохранить и позже импортировать файл с использованием формата pickle (или hd5), так как pd.read_csv часто не хватает памяти даже тогда, когда сам файл не очень большой.

import numpy as np
import pandas as pd
import pickle

df = pickle.load(open(‘data.pkl’, ‘rb’))
df.head(2)

Надеемся, наш опыт поможет и вам в работе.

Время прочтения: 5 мин.

В текущих реалиях довольно популярным инструментом исследователей данных является модуль Pandas для языка программирования Python. Аудиторам в своей работе также всё чаще приходится иметь дело со значительными объёмами информации, представленной в том или ином виде. Поэтому веяние использовать pandas в своей работе коснулось и их.

Работа с данными в pandas, когда их размер не превышает пары гигабайт, проблем не вызывает. Но когда они достигают десятков гигабайт, то обрабатывать их на обычном компьютере становится сложно. Нужно или уменьшать размер датасета или работать с данными, разбитыми на chunk, что долго и не всегда удобно.

Например, в работе при анализе операций клиентов и брокеров на финансовых рынках или транзакций по картам, для выявления мошеннических действий, когда количество таких операций составляет десятки и сотни миллионов, мы получаем долгие часы расчётов или скверное настроение, когда видим сбой вычислений из-за нехватки памяти после многих часов ожидания.

Есть другие инструменты, например, Spark, которые могут обрабатывать большие наборы данных, но для полного использования их возможностей обычно требуется более дорогое оборудование. И обычно их функционал беднее, чем у pandas.

Чтобы не менять инструмент, но при этом реализовать его использование с большими объёмами информации, мы использовали некоторые приёмы.

На первом шаге нам следует определить текущий объём памяти, который занимает датасет.

Если с числовыми значениями всё более или менее очевидно, то с объектами и строками всё запутанней. Pandas загружает в строковые столбцы как object type по умолчанию.

Чтобы заставить Pandas проверять память для каждого связанного строкового значения и возвращать истинный объем памяти, нам нужно установить параметр memory_usage в значение «deep» при вызове DataFrame.info().

df.info(memory_usage='deep')

Также мы можем использовать метод memory_usage ()

print(df.memory_usage(deep=True))
obj_cols = df.select_dtypes(include=['object'])
obj_cols_mem = obj_cols.memory_usage(deep=True)
print(obj_cols_mem)
obj_cols_sum = obj_cols_mem.sum()/1048576
print(obj_cols_sum)

Для того, чтобы подобрать нужный тип для числовых данных нужно понимать пограничные значения каждого типа и подтипа.

Используем numpy.класс iinfo для проверки минимальных и максимальных значений для каждого целочисленного подтипа:

import numpy as np
int_types = ["int8", "int16", "int32", "int64"]
for it in int_types:
     print(np.iinfo(it))

Например, определим максимальное и минимальное значение типа:

print(np.iinfo("int8").min)
print(np.iinfo("int8").max)

Теперь можно использовать такой алгоритм для поиска типа данных, который потребует наименьших затрат памяти.

col_max = df['value'].max()
col_min = df['value'].min()

if col_max <  np.iinfo("int8").max and col_min > np.iinfo("int8").min:
    df['value'] = df['value'].astype("int8")
elif col_max <  np.iinfo("int16").max and col_min > np.iinfo("int16").min:
    df['value'] df['value'].astype("int16")
elif col_max <  np.iinfo("int32").max and col_min > np.iinfo("int32").min:
    df['value'] = df['value'].astype("int32")
elif col_max <  np.iinfo("int64").max and col_min > np.iinfo("int64").min:
    df['value'] = df['value'].astype("int64")
print(df['value'].dtype)
print( df['value']dd.memory_usage(deep=True))

Но данный алгоритм не эффективен для типа float.

Чтобы помочь найти наиболее эффективный тип пространства для столбца, мы можем использовать функцию pandas.to_numeric () как для float так и для integer, не забывая указать downcast=.

float_cols = df.select_dtypes(include=['float'])
for col in float_cols.columns:
    df[col] = pd.to_numeric(df[col], downcast='float')
print(moma.select_dtypes(include=['float']).dtypes)

Некоторые столбцы object type могут являться датами, при этом тип datetime занимает меньше памяти. Мы используем функцию pandas.to_datetime() для преобразования столбца в тип datetime.

df["settledate"] = pd.to_datetime(df["settledate"])
print(df["settledate"].memory_usage(deep=True))

Начиная с версии 0,15 в Pandas ввели категориальный тип. Тип категории использует целочисленные значения для представления значений в столбце. Pandas использует отдельный словарь, который сопоставляет целочисленные значения с необработанными.

Если в категориальном столбце менее 50% уникальных значений (в противном случае выигрыша в памяти не будет), то его смело можно перевести в данный тип. Но следует учесть, что с данным типом нельзя выполнять вычисления или использовать такие методы, как min () и max ().

obj_cols = df.select_dtypes(include=['object'])
for col in obj_cols.columns:
    num_unique_values = len(df[col].unique())
    num_total_values = len(df[col])
    if num_unique_values / num_total_values < 0.5:
        df[col] = df[col].astype('category')
        
print(df.info(memory_usage='deep'))

Из всего, что мы описали выше, были случаи, когда преобразовывался уже готовый датасет. При загрузке данных мы также можем указать оптимальные типы столбцов при чтении набора данных. И тогда мы имеем на ПК уже готовый файл нужного размера, с которым сразу начинаем работать.

Pandas.read_csv() имеет несколько различных параметров, которые позволяют это сделать. Параметр dtype принимает словарь, содержащий имена столбцов (string) в качестве ключей и объекты типа NumPy в качестве значений.

import numpy as np
col_types = {"id": np.int32}
df = pd.read_csv('data.csv', dtypes=col_types)

Параметр parse_dates принимает список строк, содержащих имена столбцов, которые мы хотим разобрать как значения datetime.

df = pd.read_csv('data.csv', parse_dates=["StartDate", "EndDate"])

Используя параметр usecols, можно указать, какие столбцы мы хотим включить в исследуемые данные.

df = pd.read_csv('data.csv', usecols=["Price", "Value", “Clientcode”])
keep_cols = [
    'Price ', ' Value ', ' Clientcode ',
    'Datetradetime', 'Profit']
df = pd.read_csv("data.csv", parse

Резюмируем сказанное выше.

Для оптимизации размера, исследуемого датасета, вы можете использовать следующий алгоритм, который уже применяли мы.

  • Для всех столбцов, имеющих object type, попробуйте присвоить этим столбцам нужный тип. Как уже говорилось, по умолчанию Pandas считывает числовые столбцы как float64. Используйте pd.to_numeric чтобы сменить c float64 на 32 или 16, если это возможно.
  • Устраните nan и используйте dtypes.
  • Устраните или замените недостающие данные перед использованием pd.read_csv. Сделайте пропущенные значения -1 или 0 или что-то, что Pandas не интерпретирует как «nan». Почему? Потому что, если столбец содержит nan, Pandas автоматически делает переменную типом данных, который занимает больше памяти.
  • pd.read_csv часто назначает типы данных, которые занимают больше памяти, чем обычно, например, используя float64, когда float16 достаточно. Чтобы устранить эту проблему, можно явно объявить тип данных (и импортировать только необходимые переменные):
dtypes = {"id" : np.int32 , "operation_year" : np.int16 , "amount" : np.int8 , "contract_year" : np.int16 , "value" : np.int8}
vars = dtypes.keys()
dfp = pd.read_csv(path + "operations.csv", usecols = vars, dtype = dtypes, sep = ";", index_col="id")
  • Наконец, об этом мы ещё не говорили, но будет хорошим тоном сохранить и позже импортировать файл с использованием формата pickle (или hd5), так как pd.read_csv часто не хватает памяти даже тогда, когда сам файл не очень большой.
import numpy as np
import pandas as pd
import pickle

df = pickle.load(open('data.pkl', 'rb'))
df.head(2)

Надеемся, наш опыт поможет и вам в работе.

Memory error in python

Hello,
I want to extract the human-HCV(Hepatitis C virus) protein-protein interactions (PPI). For doing this, I have downloaded the entire content of the IntAct database as a .txt file. This .txt file has a huge size (4GB). I tried to convert this text file to a CSV file by Python and then extract just human-HCV PPIs. The problem is the size of the file, and I encounter a memory error.

input:

import pandas as pd

read_file = pd.read_csv('intact.txt', delimiter='t')
read_file.to_csv('intact.csv', index=None)`

output: `MemoryError: Unable to allocate 162. MiB for an array with shape (41, 1035669) and data type object`

how should I solve this issue?
I sincerely would appreciate your help.

Protein-Protein Interaction

python memory error

• 8.1k views

Memory errors happens a lot with python when using the 32bit Windows version . This is because 32bit processes only gets 2GB of memory to play with by default.

The solution for this error is that pandas.read_csv() function takes an option called dtype. This lets pandas know what types exist inside your csv data.

For example: by specifying dtype={‘age’:int} as an option to the .read_csv() will let pandas know that age should be interpreted as a number. This saves you lots of memory.

pd.read_csv('data.csv',dtype={'age':int})

Or try the solution below:

pd.read_csv('data.csv',sep='t',low_memory=False)

You don’t need the entire file in memory, and you don’t need pandas.

Just loop over the lines in the file, replacing tabs by commas. The following code is untested but should give you the general idea.

output = open("myoutput.csv")
for line in open("myinput.tsv"):
    output.write(line.replace('t', ','))

You don’t need Pandas for this. Or Python. Or Perl, even though one of my suggestions below uses it.

Copy the file:

cp intact.txt intact.csv

Replace tabs with commas:

perl -pi -e 's/t/,/g' intact.csv

or

sed -i 's/t/,/g' intact.csv

Login before adding your answer.

Понравилась статья? Поделить с друзьями:

Читайте также:

  • Pandas pip install error
  • Pages как изменить поля
  • Pages common error перевод
  • Pages common error egov
  • Pandas mean absolute error

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии