Речь не идет ни о каких «zip» или других утилитах сжатия. Все дело в сжатии данных!

Почему именно CSV и что такое формат CSV?

CSV (значения, разделенные запятыми) — простой и наиболее широко используемый формат данных (Excel, Google Таблицы). Большинство людей предпочитают использовать CSV, потому что он удобочитаем и обрабатывается почти всеми существующими приложениями.

Мотивация:

Данные есть везде, и в большинстве случаев они огромны. Поэтому размер набора данных свойств довольно велик для компьютеров нижнего/среднего уровня. Наиболее типичный сценарий — это когда данные из CSV-файла загружаются Pandas, но DataFrame слишком велик для обработки.

Цель: сжатие без потерь

Сжатие размера данных без потери информации

Проблема с архивированием или другими утилитами сжатия

Маловероятно, что Панды смогут его прочитать, пока данные сжаты; ему пришлось бы создать временный дубликат в несжатом виде, поэтому его сжатие на самом деле не экономит место!

Решение - › сжимайте каждую функцию в соответствии с ее типами данных.

Информацию о типах данных см. в Документации Pandas

Вот интуиция:

  1. Перебрать каждый столбец
  2. Определить, является ли столбец числовым
  3. Найти минимальное и максимальное значения
  4. Определить и применить наименьший тип данных, который может соответствовать диапазону значений

Образец кода

Пожалуйста, обратитесь к этой ссылке для ноутбука

import pandas as pd
import numpy as np
def compress_csv(dataset):
    """To save memory, walk through all of the features of a dataframe and change the data type."""
    
    # read the dataset
    df = pd.read_csv(dataset, parse_dates=True, keep_date_col=True)    
    
    # get the memory of original dataset
    original_mem = df.memory_usage().sum() / 1024**2 
    print(f'Memory usage of dataset is {original_mem:.2f} MB')
    
    # iterate all of the columns
    for col in df.columns: 
        # get data type of the column
        col_type = df[col].dtype
        # if data type is not string (as `Pandas uses the object dtype for storing strings.`)
        if col_type != object: 
            c_min = df[col].min()
            c_max = df[col].max() 
            # if data type is integer
            if str(col_type)[:3] == 'int': 
                if c_min > np.iinfo(np.int8).min and c_max < np.iinfo(np.int8).max:
                    df[col] = df[col].astype(np.int8)
                elif c_min > np.iinfo(np.int16).min and c_max < np.iinfo(np.int16).max:
                    df[col] = df[col].astype(np.int16)
                elif c_min > np.iinfo(np.int32).min and c_max < np.iinfo(np.int32).max:
                    df[col] = df[col].astype(np.int32)
                elif c_min > np.iinfo(np.int64).min and c_max < np.iinfo(np.int64).max:
                    df[col] = df[col].astype(np.int64)
            # if data type is float    
            else: 
                if c_min > np.finfo(np.float16).min and c_max < np.finfo(np.float16).max:
                    df[col] = df[col].astype(np.float16)
                elif c_min > np.finfo(np.float32).min and c_max < np.finfo(np.float32).max:
                    df[col] = df[col].astype(np.float32)
                else:
                    df[col] = df[col].astype(np.float64)
        # if data type is object(string)
        else: 
            df[col] = df[col].astype('category')
    
    # get the memory of compressed dataaset
    compressed_mem = df.memory_usage().sum() / 1024**2 
    print(f'Memory usage after optimization is: {compressed_mem:.2f}')
    print(f'Compressed by {100*(original_mem - compressed_mem) / original_mem:.1f}%')

И вот наш результат

print('-' * 40)
compress_csv("../KAGGLE/mean-imputation/data.csv")
print('-' * 40)
compress_csv("../datasets/titanic.csv")
print('-' * 40)
compress_csv("../datasets/bureau_balance.csv")
print('-' * 40)
compress_csv('../datasets/hotel_bookings.csv')
print('-' * 40)
----------------------------------------
Memory usage of dataset is 617.98 MB
Memory usage after optimization is: 132.56
Compressed by 78.5%
----------------------------------------
Memory usage of dataset is 0.28 MB
Memory usage after optimization is: 0.04
Compressed by 85.7%
----------------------------------------
Memory usage of dataset is 624.85 MB
Memory usage after optimization is: 156.21
Compressed by 75.0%
----------------------------------------
Memory usage of dataset is 29.15 MB
Memory usage after optimization is: 4.71
Compressed by 83.8%
---------------------------------------

БИНГОУУУ! Все наборы данных были уменьшены на 75–85 %. Результат многообещающий и эффективный с точки зрения памяти. Вам больше не нужно беспокоиться о проблеме использования памяти с Pandas.

Однако мы сжимали только числовые типы данных, а не объектные. Сжатие типов данных объекта немного сложно. О том, как сжимать типы данных объектов, мы поговорим в следующих статьях.

Заключение

В этой статье мы увидели, как эффективно сжимать файлы CSV и оптимизировать использование памяти данными. Это важно, когда возникает проблема с памятью при подборе наборов данных в локальной памяти.

Я надеюсь, что вы найдете статью полезной. Пожалуйста, не стесняйтесь связаться со мной в разделе комментариев ниже. Любые отзывы и предложения приветствуются!