MATLAB将单元阵列保存到NetCDF文件

MATLAB将单元阵列保存到NetCDF文件,matlab,netcdf,Matlab,Netcdf,我有一个.csv文件,我使用导入数据函数作为列向量导入到MATLAB中。.csv文件中的每一列现在都是大小为7286x1的单元格数组。如何将这些列向量作为变量保存到netcdf文件中 ncid = netcdf.create('WI_O3.nc', 'NOCLOBBER'); dimid = netcdf.defDim(ncid, 'my_dim', 7286); SiteID = netcdf.defVar(ncid, 'AQS_SITE_ID', 'double', dimid); netc

我有一个.csv文件,我使用导入数据函数作为列向量导入到MATLAB中。.csv文件中的每一列现在都是大小为7286x1的单元格数组。如何将这些列向量作为变量保存到netcdf文件中

ncid = netcdf.create('WI_O3.nc', 'NOCLOBBER');
dimid = netcdf.defDim(ncid, 'my_dim', 7286);
SiteID = netcdf.defVar(ncid, 'AQS_SITE_ID', 'double', dimid);
netcdf.endDef(ncid);
netcdf.putVar(ncid, SiteID, AQS_SITE_ID);
    % Error using netcdf.putVar (line 56)
    % Expected DATA to be one of these types:
    % 
    % double, single, uint8, uint16, uint32,
    % uint64, int8, int16, int32, int64, char
    % 
    % Instead its type was cell.
我怎样才能把我所有的单元格转换成一个字符串或是双精度的,或者任何能让它工作的东西?我的一些单元格是由字符串组成的,而另一些单元格是双精度数字


是否有更快的方法将工作区中的所有变量保存到一个.nc文件中,保持所有变量名称相同就可以了?

netcdf.*函数是直接访问netcdf库的低级函数。 将ncwrite与nccreate一起使用

查看for NCCREATE和for NCWRITE,其中显示了如何创建变量以及所需的维度,然后写入变量。NCWRITE doc页面中的第二个示例应该是一个很好的起点


NetCDF格式不支持“单元格”。在MATLAB中创建一个ND变量作为普通数字数组,然后将其写入NetCDF文件。

NetCDF.*函数是直接访问NetCDF库的低级函数。 将ncwrite与nccreate一起使用

查看for NCCREATE和for NCWRITE,其中显示了如何创建变量以及所需的维度,然后写入变量。NCWRITE doc页面中的第二个示例应该是一个很好的起点


NetCDF格式不支持“单元格”。在MATLAB中创建一个ND变量作为普通数字数组,然后将其写入NetCDF文件。

这并不是您所要求的,但这里有一个脚本,它将结构中的所有{double,single,char}变量写入NetCDF文件。这不是最通用的代码,因为我只处理3D变量,尽管这很容易扩展。我把它贴在这里是因为我认为它可能是通用的和有趣的,也许有人甚至会发布一个更好的版本

我还压缩了所有不是标量或字符的变量

function struct2nc(x,ncfile,ncfiletype,deflate_lev)
% STRUCT2NC writes all float,double and character vars to netcdf
% Usage: struct2nc(x,ncfile,[ncfiletype],[deflate_lev])
% x = structure
% ncfile = name of netcdf output file (e.g. 'test.nc')
% ncfiletype = netcdf file type (e.g. 'classic','netcdf4_classic')
% deflate_lev = deflate level (0-9, 0 is none)
%
% This function writes all 'double','single' and 'char' variables
% to NetCDF using the native Matlab NetCDF interface.  It skips all
% other classes in the struct (e.g. structs, cell arrays, etc).  It
% also only handles scalar, 1D, 2D, and 3D arrays currently, although
% this could easily be extended.

if nargin==2,
    ncfiletype='classic';
    deflate_lev=0;
elseif nargin==3;
    switch ncfiletype
        case {'netcdf4','netcdf4_classic'}
            deflate_lev=6;
        otherwise
            deflate_lev=0;
    end
end
s = fieldnames(x);
k=0;
% create variables first, but don't write data
for i=1:length(s)
    vname=char(s(i));
    var=x.(vname);
    vtype = class(var);
    vshape = size(var);
    ndims = length(vshape);
    vlen = length(var(:));
    switch vtype;
        case {'double','single'},
            if vlen==1,
                nccreate(ncfile,vname,...
                    'Datatype',vtype,'format',ncfiletype);
                k=k+1;
                vnames{k}=vname;
            else
                if min(vshape)==1,
                    nccreate(ncfile,vname,...
                        'Datatype',vtype,...
                        'DeflateLevel',deflate_lev,...
                        'Dimensions',{[vname '1'] vlen},...
                        'format',ncfiletype);
                    k=k+1;
                    vnames{k}=vname;
                elseif ndims==2,
                    nccreate(ncfile,vname,...
                        'Datatype',vtype,...
                        'DeflateLevel',deflate_lev,...
                        'Dimensions',{[vname '1'] vshape(1) [vname '2'] vshape(2)},...
                        'format',ncfiletype);
                    k=k+1;
                    vnames{k}=vname;
                elseif ndims==3,
                    nccreate(ncfile,vname,...
                        'Datatype',vtype,...
                        'DeflateLevel',deflate_lev,...
                        'Dimensions',...
                        {[vname '1'] vshape(1) [vname '2'] vshape(2) [vname '3'] vshape(3)},...
                        'format',ncfiletype);
                    k=k+1;
                    vnames{k}=vname;
                else,
                    disp('Skipping variable with more than 3 dimensions');
                end
            end
        case {'char'},
            nccreate(ncfile,vname,...
                'Datatype',vtype,...
                'Dimensions',{[vname '1'] vlen},.....
                'format',ncfiletype);
            k=k+1;
            vnames{k}=vname;
        otherwise,
            disp(['skipping ' vname])
    end
end
%write all the data at the end
for i=1:length(vnames)
    ncwrite(ncfile,vnames{i},x.(vnames{i}));
end

这不完全是您所要求的,但这里有一个脚本,它将结构中的所有{double,single,char}变量写入netcdf文件。这不是最通用的代码,因为我只处理3D变量,尽管这很容易扩展。我把它贴在这里是因为我认为它可能是通用的和有趣的,也许有人甚至会发布一个更好的版本

我还压缩了所有不是标量或字符的变量

function struct2nc(x,ncfile,ncfiletype,deflate_lev)
% STRUCT2NC writes all float,double and character vars to netcdf
% Usage: struct2nc(x,ncfile,[ncfiletype],[deflate_lev])
% x = structure
% ncfile = name of netcdf output file (e.g. 'test.nc')
% ncfiletype = netcdf file type (e.g. 'classic','netcdf4_classic')
% deflate_lev = deflate level (0-9, 0 is none)
%
% This function writes all 'double','single' and 'char' variables
% to NetCDF using the native Matlab NetCDF interface.  It skips all
% other classes in the struct (e.g. structs, cell arrays, etc).  It
% also only handles scalar, 1D, 2D, and 3D arrays currently, although
% this could easily be extended.

if nargin==2,
    ncfiletype='classic';
    deflate_lev=0;
elseif nargin==3;
    switch ncfiletype
        case {'netcdf4','netcdf4_classic'}
            deflate_lev=6;
        otherwise
            deflate_lev=0;
    end
end
s = fieldnames(x);
k=0;
% create variables first, but don't write data
for i=1:length(s)
    vname=char(s(i));
    var=x.(vname);
    vtype = class(var);
    vshape = size(var);
    ndims = length(vshape);
    vlen = length(var(:));
    switch vtype;
        case {'double','single'},
            if vlen==1,
                nccreate(ncfile,vname,...
                    'Datatype',vtype,'format',ncfiletype);
                k=k+1;
                vnames{k}=vname;
            else
                if min(vshape)==1,
                    nccreate(ncfile,vname,...
                        'Datatype',vtype,...
                        'DeflateLevel',deflate_lev,...
                        'Dimensions',{[vname '1'] vlen},...
                        'format',ncfiletype);
                    k=k+1;
                    vnames{k}=vname;
                elseif ndims==2,
                    nccreate(ncfile,vname,...
                        'Datatype',vtype,...
                        'DeflateLevel',deflate_lev,...
                        'Dimensions',{[vname '1'] vshape(1) [vname '2'] vshape(2)},...
                        'format',ncfiletype);
                    k=k+1;
                    vnames{k}=vname;
                elseif ndims==3,
                    nccreate(ncfile,vname,...
                        'Datatype',vtype,...
                        'DeflateLevel',deflate_lev,...
                        'Dimensions',...
                        {[vname '1'] vshape(1) [vname '2'] vshape(2) [vname '3'] vshape(3)},...
                        'format',ncfiletype);
                    k=k+1;
                    vnames{k}=vname;
                else,
                    disp('Skipping variable with more than 3 dimensions');
                end
            end
        case {'char'},
            nccreate(ncfile,vname,...
                'Datatype',vtype,...
                'Dimensions',{[vname '1'] vlen},.....
                'format',ncfiletype);
            k=k+1;
            vnames{k}=vname;
        otherwise,
            disp(['skipping ' vname])
    end
end
%write all the data at the end
for i=1:length(vnames)
    ncwrite(ncfile,vnames{i},x.(vnames{i}));
end

有趣的问题。AFAIK、NetCDF3和NetCDF4格式与Matlab的单元数组没有任何相似之处,它们可以在每个单元中保存不同类型的数据。不幸的是,Matlab目前1/18都不支持读取和写入NetCDF4的可变长度字符串,即使它最近添加了字符串数据类型

因此,有两种可能的解决方案

使用sprintf…将所有数字数据转换为字符串。。。。不幸的是,这些字符串必须是固定长度的字符串,需要足够长才能保持必要的精度。然后将数据存储为固定长度的二维字符数组

用数值对字符串数据进行编码。例如,如果有臭氧、二氧化碳、甲烷串,则分别用-999、-998和-997替换它们。显然,选择实际数据中无法出现的数值。这类似于编码nan的方式,由属性_FillValue标记。您还应该将标志和相应的原始字符串存储为属性或单独的字符数组和相关标志值


有趣的问题。AFAIK、NetCDF3和NetCDF4格式与Matlab的单元数组没有任何相似之处,它们可以在每个单元中保存不同类型的数据。不幸的是,Matlab目前1/18都不支持读取和写入NetCDF4的可变长度字符串,即使它最近添加了字符串数据类型

因此,有两种可能的解决方案

使用sprintf…将所有数字数据转换为字符串。。。。不幸的是,这些字符串必须是固定长度的字符串,需要足够长才能保持必要的精度。然后将数据存储为固定长度的二维字符数组

用数值对字符串数据进行编码。例如,如果有臭氧、二氧化碳、甲烷串,则分别用-999、-998和-997替换它们。显然,选择实际数据中无法出现的数值。这类似于编码nan的方式,由属性_FillValue标记。您还应该将标志和相应的原始字符串存储为属性或单独的字符数组和相关标志值


我很难将细胞转换成一个字符串,当它是像“臭氧”这样的东西时。帮助我尝试了cellstr,但也可以,我必须分别添加每个变量?当单元格被删除时,我很难将其转换为字符串
这是“臭氧”之类的东西。帮助我尝试了cellstr,但也可以,我必须分别添加每个变量?相关:取决于Matlab版本相关:取决于Matlab版本