>我有很多大的.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%
我是否缺少压缩设置?还是别的什么?
我找到了自己问题的答案...
- 为每个变量启用压缩
- 对于列
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 字节。压缩将进一步减小文件大小,尤其是对于非随机数据:-(