【问题标题】:How to write variables in a loop while creating netCDF file in python在python中创建netCDF文件时如何在循环中写入变量
【发布时间】:2021-11-05 13:55:37
【问题描述】:

我在 .csv 文件中有 200 多个时间序列变量,并且想将所有变量写入 netCDF 文件。但我不知道为什么我不能在一个循环中做到这一点。伪数据代码如下:

数据生成

vars = ['one', 'two', 'three', 'four']
date = pd.date_range(start='2021-01-01', end='2021-01-12')
data_dict = {k: np.random.rand(12) for k in vars}
data = pd.DataFrame(data_dict, index=date)

创建具有维度的 netcdf 文件

try:
    # just to be safe, make sure dataset is not already open.
    ncfile.close()
except:
    pass

ncfile = Dataset('test.nc', mode='w', format='NETCDF4_CLASSIC')

lat_dim = ncfile.createDimension('lat', 1)    
lon_dim = ncfile.createDimension('lon', 1)    

time_dim = ncfile.createDimension('time', None) 
time = ncfile.createVariable('time', np.float64, ('time',))
time.units = 'Minutes since 2021-01-01 0'
time.long_name = 'time'
    
calendar = 'standard'
time[:] = date2num(
    (pd.to_datetime(data.index)).to_pydatetime(),
    units=time.units,
    calendar=calendar
)

循环写入netcdf文件

for i, vname in enumerate(var):
    vname = ncfile.createVariable(vname,np.float64,'time')
    vname[:] = data[vname].values

我认为这里的问题是'vname',它是一个字符串。我试图将它转换为一个对象,但无法做到这一点。我不确定我是否错了。 任何帮助或建议将不胜感激

【问题讨论】:

    标签: python-3.x netcdf python-xarray enumerate netcdf4


    【解决方案1】:

    使用xarray,您可以编写如下内容:

    import numpy as np
    import pandas as pd
    
    variables = ['one', 'two', 'three', 'four']
    date = pd.date_range(start='2021-01-01', end='2021-01-12')
    data_dict = {k: np.random.rand(12) for k in variables}
    data = pd.DataFrame(data_dict, index=date)
    data.index.name = 'time'
    
    ds = data.to_xarray().expand_dims(dim=['lat', 'lon'])
    ds.to_netcdf('test.nc', format='NETCDF4')
    

    to_xarray 方法会给你一个xarray.Datasettime 作为坐标和你的四个变量。而expand_dims 增加了两个空间维度。

    如果生成的数据集/netcdf 不是您想要的,请告诉我。

    【讨论】:

    • 嗨@cyril,是的,它会创建包含所有变量的 netcdf 文件,但如果我想添加更多信息,如单位、每个变量的描述,那么如何将此信息添加到每个变量
    • 您可以在创建ds 后添加属性:ds['time'].attrs.update({"long_name": "time"})。对于calendarunits 属性,xarray 会在写入test.nc 时自动写入它们。不过,如果你想给自己设置单位,你可以写ds['time'].encoding.update({"units": "Minutes since 2021-01-01"})。希望这会有所帮助!
    • 谢谢你的帮助
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-21
    • 1970-01-01
    • 1970-01-01
    • 2016-04-24
    • 2022-08-09
    • 2020-10-05
    • 1970-01-01
    相关资源
    最近更新 更多