代码之家  ›  专栏  ›  技术社区  ›  SugaKookie

在MATLAB中将一组字符串保存到NetCDF中

  •  0
  • SugaKookie  · 技术社区  · 6 年前

    我有一个字符串列表,我想用MATLAB保存到netCDF中。但是,创建文件时遇到问题。

    method_ID 是这样的char数组:

    '55-059-0019-88101-1'
    '55-059-0019-88101-1'
    '55-059-0019-88101-1'
    '55-059-0019-88101-1'
    '55-059-0019-88101-1'
    '55-059-0019-88101-1'
    '55-059-0019-88101-1'
    '55-059-0019-88101-1'
    '55-059-0019-88101-1'
    '55-059-0019-88101-1'
    

    我尝试执行以下操作,但它将字符串保存为一个长字符串,而不是10个字符串。

    filename = ['PM25_24hr_',num2str(years(y)),'_EPA_AQS.nc'];
    ncfilename = ['/data3/jg3223/PM25/netCDF/',filename]; 
    
    method_ID = char(data_PM25{:,1});
    
    % Create the file, overwriting if already exists (Clobber) and
    % 64-bit offset (Allow easier creation of files and variables which are larger
    % than two gigabytes.)
    mode = bitor(netcdf.getConstant('CLOBBER'),netcdf.getConstant('64BIT_OFFSET'));
    ncid = netcdf.create(ncfilename,mode);
    
    % Define (file) global attributes
    globalVarId=netcdf.getConstant('GLOBAL');
    netcdf.putAtt(ncid,globalVarId,'name','PM25_24hr_AQS');
    
    [a,b] = size(method_ID);
    IDDimId = netcdf.defDim(ncid,'method_ID',a*b); % I know this size is wrong, but using `length(method_ID)` runs a size error later on
    
    % Define variables, starting with coordinate variables,
    % with appropriate names, types, and dimensions
    IDVarId = netcdf.defVar(ncid,'method_ID','char',IDDimId);
    
    % Exit the "define mode", i.e., structure creation mode
    netcdf.endDef(ncid);
    
    method ID
    netcdf.putVar(ncid,IDVarId,method_ID);
    
    % Close the netCDF file
    netcdf.close(ncid);
    
    1 回复  |  直到 6 年前
        1
  •  2
  •   Packard CPW    6 年前

    如果使用“经典字符串”,则应定义二维。

    可以使用netCDF以两种方式存储字符串,“经典字符串”和“字符串数组”( https://www.unidata.ucar.edu/software/netcdf/netcdf-4/newdocs/netcdf-c/Strings.html ). "经典字符串“不需要NetCDF4.0+版本,下面的答案就是基于此。

    %% Solution using classic string (without NETCDF-4)
    
    ncfilename ='./AQS.nc';
    uint_method=uint8('55-059-0019-88101-1');
    method_ID = char(repmat(uint_method,10,1));
    [a,b] = size(method_ID);  %a=10, b=19
    
    mode = bitor(netcdf.getConstant('CLOBBER'),netcdf.getConstant('64BIT_OFFSET'));
    ncid = netcdf.create(ncfilename,mode);
    
    globalVarId=netcdf.getConstant('GLOBAL');
    netcdf.putAtt(ncid,globalVarId,'name','PM25_24hr_AQS');
    
    %IDDimId = netcdf.defDim(ncid,'method_ID',a*b);
    % IDDimId = netcdf.defDim(ncid,'method_ID',length(method_ID)); % ERROR: input elements does not match the variable size
    % IDVarId = netcdf.defVar(ncid,'method_ID','char',IDDimId);
    
    IDDim1 = netcdf.defDim(ncid,'charlen',b);
    IDDim2 = netcdf.defDim(ncid,'methods',a);
    IDVarId = netcdf.defVar(ncid,'method_ID','char',[IDDim1 IDDim2]);
    
    netcdf.endDef(ncid);
    netcdf.putVar(ncid,IDVarId,method_ID'); %transpose
    netcdf.close(ncid);
    

    你将得到:

    $ ncdump AQS.nc 
    netcdf AQS {
    dimensions:
        charlen = 19 ;
        methods = 10 ;
    variables:
        char method_ID(methods, charlen) ;
    
    // global attributes:
            :name = "PM25_24hr_AQS" ;
    data:
    
     method_ID =
      "55-059-0019-88101-1",
      "55-059-0019-88101-1",
      "55-059-0019-88101-1",
      "55-059-0019-88101-1",
      "55-059-0019-88101-1",
      "55-059-0019-88101-1",
      "55-059-0019-88101-1",
      "55-059-0019-88101-1",
      "55-059-0019-88101-1",
      "55-059-0019-88101-1" ;
    }