csv 到 netCDF 生成的 .nc 文件比原始.csv大 4 倍



>我有很多大的.csv文件,我想用xrray转换为.nc(即netCDF文件(。但是,我发现保存 .nc 文件需要很长时间,并且生成的 .nc 文件比原始.csv文件大得多(4 到 12 倍

(。

下面的示例代码显示了相同的数据如何生成比保存在 .csv 中时大约 4 倍的 .nc 文件

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 文件大约是 .csv 文件的 4 倍。

我发现这篇文章建议从类型"字符串"更改为类型"char"会大大减少文件大小,但是如何在 xarray 中执行此操作?

另外,请注意,即使将所有数据都作为整数(即注释掉df['e'] = df['e'].astype(str)(,生成的.nc文件仍然比.csv大50%

我是否缺少压缩设置?还是别的什么?

我找到了自己问题的答案...

  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 字节。压缩将进一步减小文件大小,尤其是对于非随机数据:-(

最新更新