2014-01-10 1 views
1

데이터 가져 오기 기능을 사용하여 MATLAB으로 가져온 .csv 파일을 열 벡터로 사용하고 있습니다. .csv 파일의 각 열은 이제 7286x1 크기의 셀 배열입니다. 어떻게 이러한 각 열 벡터를 변수로 netcdf 파일에 저장할 수 있습니까?MATLAB 셀 배열을 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 파일로 저장하는 더 빠른 방법이 있습니다. 모든 변수 이름을 동일하게 유지하십시오. 괜찮습니다)?

답변

3

당신이 물어 본 것은 정확하지 않지만, 구조의 모든 {double, single, char} 변수를 netcdf 파일에 쓰는 스크립트가 있습니다. 3D 변수까지만 처리하기 때문에 가장 일반적인 코드는 아닙니다 (확장하기는 쉽지만). 내가 일반적인 사용과 관심이 될 수 있다고 생각하기 때문에 여기에 게시하고 있습니다. 아마도 누군가는 더 나은 버전을 게시 할 것입니다.

또한 스칼라 또는 char이 아닌 모든 변수를 압축합니다.

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 
+1

관련 항목 : [cell2struct] (http://www.mathworks.com/help/matlab/ref/cell2struct.html) (Matlab 버전에 따라 다름) – ZZZ

0

netcdf. * 함수는 NetCDF 라이브러리에 직접 액세스하기위한 하위 수준 함수입니다. nccwrite와 함께 ncwrite를 사용하십시오.

NCCREATE의 경우 example을, NCWRITE의 경우 example을보고 필요한 치수와 함께 변수를 작성한 다음 작성하는 방법을 보여줍니다. (NCWRITE 문서 페이지의 두 번째 예제는 좋은 출발점이어야합니다).

NetCDF 형식은 '셀'을 지원하지 않습니다. MATLAB에서 ND 변수를 일반 숫자 배열로 만든 다음 NetCDF 파일에 씁니다.

+0

'오존'과 같은 셀을 문자열로 변환하는 데 문제가 있습니다. 도움? 'cellstr'을 시도했지만 작동하지 않습니다. – shizishan

+0

또한 각 변수를 따로 추가해야합니까? – shizishan

0

흥미로운 문제. AFAIK, NetCDF3 및 NetCDF4 형식에는 각 셀에 다른 유형의 데이터를 저장할 수있는 Matlab의 셀 배열과 유사한 것이 없습니다. 유감스럽게도 Matlab은 현재 (1/18) NetCDF4의 가변 길이 문자열을 읽고 쓸 수있는 기능을 지원하지 않습니다 (최근에 문자열 데이터 형식을 추가 했음에도 불구하고).

두 가지 가능한 솔루션.

  1. 모든 숫자 데이터를 sprintf (...)로 문자열로 변환하십시오. 불행히도 고정 길이의 문자열이 필요하며 이는 필요한 정밀도를 유지할만큼 길어야합니다. 그런 다음 데이터를 고정 길이 2 차원 문자 배열로 저장하십시오.

  2. 문자열 데이터를 숫자 값으로 인코딩하십시오. 예를 들어, "Ozone", "CO2", "Methane"이라는 문자열이있는 경우이를 각각 -999, -998 및 -997로 바꿉니다. (분명히 실제 데이터에서 발생할 수없는 숫자 값을 선택하십시오.) 이는 _FillValue 속성으로 플래그 된 nan을 인코딩해야하는 것과 유사합니다. 또한 플래그 및 해당 원래 문자열을 특성 또는 문자 및 관련 플래그 값의 개별 배열로 저장해야합니다.