csv to netCDF создает файлы.nc, которые в 4 раза больше оригинальных.csv

У меня есть много больших файлов.csv, которые я хочу преобразовать в.nc (т.е. файлы netCDF), используя xrray. Однако я обнаружил, что сохранение файлов.nc занимает очень много времени, и полученные файлы.nc намного больше (в 4–12 раз больше), чем исходные файлы.csv.

Ниже приведен пример кода, демонстрирующий, как одни и те же данные создают файлы.nc, которые примерно в 4 раза больше, чем при сохранении в.csv.

import pandas as pd
import xarray as xr
import numpy as np
import os

# Create pandas DataFrame 
df = pd.DataFrame(np.random.randint(low=0, high=10, size=(100000,5)),
                   columns=['a', 'b', 'c', 'd', 'e'])

# Make 'e' a column of strings
df['e'] = df['e'].astype(str)

# Save to csv
df.to_csv('df.csv')

# Convert to an xarray's Dataset
ds = xr.Dataset.from_dataframe(df)

# Save NetCDF file
ds.to_netcdf('ds.nc')

# Compute stats
stats1 = os.stat('df.csv')
stats2 = os.stat('ds.nc')
print('csv=',str(stats1.st_size))
print('nc =',str(stats2.st_size))
print('nc/csv=',str(stats2.st_size/stats1.st_size))

Результат:

>>> csv = 1688902 bytes
>>>  nc = 6432441 bytes
>>> nc/csv = 3.8086526038811015

Как видите, файл.nc примерно в 4 раза больше, чем файл.csv.

Я обнаружил, что этот пост предполагает, что переход от типа 'string' к типу 'char' значительно уменьшает размер файла, но как мне это сделать в xarray?

Кроме того, обратите внимание, что даже когда все данные имеют целочисленные значения (т. Е. Комментарий df['e'] = df['e'].astype(str)) полученный файл.nc по-прежнему на 50% больше, чем.csv

Я пропускаю настройку сжатия? ...или что-то другое?

2 ответа

Я нашел ответ на свой вопрос...

  1. Включить сжатие для каждой переменной
  2. Для колонки eукажите, что dtype это "характер" (то есть S1)

Перед сохранением файла.nc добавьте следующий код:

encoding = {'a':{'zlib':True},
            'b':{'zlib':True},
            'c':{'zlib':True},
            'd':{'zlib':True},
            'e':{'zlib':True, 'dtype':'S1'}}
ds.to_netcdf('ds.nc',format='NETCDF4',engine='netcdf4',encoding=encoding)

Новые результаты:

>>> csv = 1688902 bytes
>>>  nc = 1066182 bytes
>>> nc/csv = 0.6312870729029867

Обратите внимание, что для сохранения файла.nc все еще требуется некоторое время.

Поскольку вы используете только переменную в диапазоне от 0 до 9, в файле CSV для хранения данных достаточно 1 байта. xarray, использует целочисленные значения int64 (8 байт) по умолчанию.

Чтобы указать xarray использовать 1-байтовые целые, вы можете использовать это:

 ds.to_netcdf('ds2.nc',encoding = {'a':{'dtype': 'int8'},
      'b':{'dtype': 'int8'}, 'c':{'dtype': 'int8'}, 
      'd':{'dtype': 'int8'}, 'e':{'dtype': 'S1'}})

Полученный файл имеет размер 1307618 байт. Сжатие уменьшит размер файла еще больше, особенно для неслучайных данных:-)

Другие вопросы по тегам