【问题标题】:read textscan file with NA as empty matlab读取带有NA的textscan文件作为空matlab
【发布时间】:2015-08-28 05:06:09
【问题描述】:

我有一个包含 n 行和 5 列的文本文件 D 我想阅读。每行将代表一个向量。但是,如果值等于 NA,我想将其留空:

D:

122 12 10 NA NA
110 10 30 45 87 
110 12 10 NA NA
..

我正在这样做:

bid = fopen(D,'r');
bfile = textscan(bid,'%d %d %d %s %s','TreatAsEmpty',{'NA'})
var=122;
IndVar=bfile {:,1}==var;
rest=bfile(:,[2:end])
vecVar=rest(IndVar)

我想从没有 NA 的行中获取向量: vecVar = [12 10]; [10 30 45 87]; [12 10];

我试试这个:

rest= rest(~isnan(rest));

我得到错误:

'cell' 类型的输入参数的未定义函数 'isnan'。

我已经玩了一个多小时了仍然无法弄清楚.. 任何帮助将不胜感激!

非常感谢!

【问题讨论】:

  • 如果你在命令窗口中输入size(rest),你会得到什么?
  • @CST-Link size (rest) 给出 ans= 1 4. 虽然应该是 n-row X 4..
  • 问题是,textscan 对于按列获取数据很有用,但您需要按行过滤数据。
  • @CST-Link 您可以建议任何特定命令吗?
  • 不幸的是,textscan 很容易替换。致力于解决方案。同时,问题:只有最后两列可以包含NA?还是全部?

标签: matlab nan


【解决方案1】:

如错误消息中所述,isnan 仅适用于数值数组。要对数值数组的元胞数组进行操作,请使用cellfun,它将对数组中的每个元胞应用一个命令。顺便说一句,NaN 内部实际上是一个数字(单数或双数),因此您将希望使用数字版本的 NaN 而不是文本字符串 'NA' 为您的空值,@987654324 @ 是一个内置命令,因此您需要更改该变量名称。

您需要稍微澄清一下,但据我了解,给定包含矩阵的输入文件:

122 12 10 NA NA
110 10 30 45 87 
110 12 10 NA NA

你期望:

vecVar ={...
    [12 10];
    [10 30 45 87 ];
    [12 10]
    };

在我的第一个答案中,我错过了您正在阅读整数的事实。这将给出上面的结果,我认为这就是你所追求的:

bid = fopen(d,'r');
% integers don't have NaN, so read in as float instead.
% also, collect everything into a single matrix because it makes it.
% easier to debug
bfile = textscan(bid,'%f %f %f %f, %f', 'TreatAsEmpty', 'NA', 'CollectOutput', true);
fclose(D);

% convert from a cell to a matrix to make i
bfile = bfile{1};
var=122;
IndVar = bfile(:,1) == var;
rest = bfile(:, 2:end);

% Turn the matrix back into a cell with each row a single cell
[nrows, ncols] = size(rest);
rest = mat2cell(rest, ones(nrows, 1), ncols);

% get rid of the NaN values
rest = cellfun(@(x) x(~isnan(x)), rest, 'UniformOutput', false);

这将生成一个元胞数组,其中每个元素都包含一个可以使用desired_vector = rest{index_of_your_choice};检索的向量

【讨论】:

  • 谢谢。但是,我收到此错误:“cell”类型的输入参数的未定义函数“isnan”。 @(x)all(~isnan(x)) 中的错误...当我使用 %d 而不是字符串时,rest(IndVar) 给了我 ans = [90x1 int32] 当我应该得到 1 x 4 ..我在做什么错了吗?
  • 好的,谢谢!我得到了“休息”,这是单元格数组。如何将其转换为法线向量?
  • 这个答案也将“rest”设置为 90 x 2 数组..当第二行不同时..它有 4 列但仍然只读取前 2 列..
  • 我之前错过的几个问题,将更新我的答案。首先,您将最后两列作为字符串读取,因此isnan 不知道如何处理这些内容。如果您将它们读入整数 (%d),则没有整数 NaNNaN 只能是单人或双人。
【解决方案2】:

以下是在元胞数组val 中放入每行数值的代码:

    %'Number of columns'
    NC = 5;

    %'Read the strings'
    f = fopen('test.txt', 'r');
    raw= textscan(f, repmat('%s',1,NC));
    fclose(f);
    if numel(raw) ~= NC
            error('Something is wrong with the file format');
    else
            NR = numel(raw{1});
    end;

    %'Convert data'
    for c = 1:NC
            for r = 1:NR
                    raw{c}{r} = sscanf(raw{c}{r}, '%d');
            end;
    end;

    %'Concatenate rows into val'
    val = cell(1,NR);
    buf = cell(1,NC);
    for r = 1:NR
            for c = 1:NC
                    buf{c} = raw{c}{r};
            end;
            val{r} = [buf{:}];
    end;

您不能使用普通矩阵来存储值,因为存在具有不同数量值的行。这意味着行向量只能存储到元胞数组中。

【讨论】:

  • 谢谢。我花了一段时间才得到这个代码。我从前面的代码中得到了我的“val”。我想知道如何访问第一列等于“val”的行?
  • @mil 不确定我是否理解这个问题。但是,使用我提供的代码,可以通过val{1} 获取第一行,通过val{2} 获取第二行等。要获取第二行中的第一列,可以编写val{2}(1)。要找出第三行有多少列,可以使用numel(val{3})。请注意,如果您尝试访问最初具有值 NA 的列,则会收到错误消息。
  • 抱歉听起来很愚蠢。但我仍然无法弄清楚。我在我的代码中写了 val=122;IndVar=bfile {:,1}==val;。我从以前的某个地方得到“val”值。所以我想知道如何获得第一列==122..即我使用索引 IndVar.. 的行(列来自 2:NC)
猜你喜欢
  • 2011-10-03
  • 2016-07-20
  • 1970-01-01
  • 2013-09-12
  • 2017-05-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-26
相关资源
最近更新 更多