在 Scilab 中打开具有不同行和列结构的文件

Opening a file of varying row and column structure in Scilab

我习惯性地在 scilab 中使用 csvRead 来读取我的数据文件,但是我现在面对的是一个包含 200 行块的文件,前面是 3 行 headers,所有这些我都想接受考虑到。

我尝试按照 csvRead 的 scilab 帮助网站上的示例指定数据范围(示例就在页面底部)(https://help.scilab.org/doc/6.0.0/en_US/csvRead.html),但我总是得出相同的结果错误消息:

The line and/or colmun indices are outside of the limits

Error in the column structure.

我的前三行是 header,我知道这会导致问题,但即使我从 block-range 中省略它们,我仍然遇到同样的问题。

否则,我的数据是这样排序的,即我有三行 headers(两行包含一个 header,仅包含一或两列,一行包含一个 header 在所有列上),200 行数据和一个空行 - 这表示来自一张图像的数据,我在文件中有大约 500 张图像,我希望能够读取和处理所有这些图像并跟踪headers 因为它们说明了我稍后需要引用的图像编号。示例:

DTN-dist_Devissage-1_0006_0,,,,,,
L0,,,,,,
X [mm],Y [mm],W [mm],exx [1] - Lagrange,eyy [1] - Lagrange,exy [1] - Lagrange,Von Mises Strain [1] - Lagrange
-1.13307,-15.0362,-0.00137507,7.74679e-05,8.30045e-05,5.68249e-05,0.00012711
-1.10417,-14.9504,-0.00193334,7.66086e-05,8.02914e-05,5.43132e-05,0.000122655
-1.07528,-14.8647,-0.00249155,7.57493e-05,7.75786e-05,5.18017e-05,0.0001182

有人对此有解决方案吗?

我当前的代码,遵循 Scilab-help 示例的改编版本,如下所示(我尝试将块大小和 iblock 值更改为 include/omit headers:

blocksize=200;
C1=1;
C2=14;
iblock=1
while (%t)
    R1=(iblock-1)*blocksize+4;
    R2=blocksize+R1-1;
    irange=[R1 C1 R2 C2];
    V=csvRead(filepath+filename,",",".","",[],"",irange);
   iblock=iblock+1
end

错误

CSV

你的很多问题都来自于你的csv文件中昏迷数的不一致。在 LibreOffice Calc 中打开它并保存它会放置正确数量的逗号,即使在空行上也是如此。

R1

您当前的代码没有将 R1 置于值的开头。正确的公式是

R1=(iblock-1)*(blocksize+blanksize+headersize)+1+headersize;

文件结束

目前您的代码引发错误和文件结尾,因为 R1 变得大于行数。要解决此问题,您可以指定最大块数或根据行数测试 R1 的值。

改进了更大文件的解决方案。

在解决您的大文件问题时,出现了两个问题:

  1. 我们需要知道块数或行数
  2. csvRead 的每次调用都非常慢,因为它在每次调用时处理整个文件(1 秒/块!)

我的想法是读取整个文件并将其存储在字符串矩阵中(自从 6.0.0 以来改进了 mgetl),然后在子矩阵上使用 csvTextScan。这样做也删除了block/lines.

的数字的手动写入

代码如下:

clear all
clc

s = filesep()
filepath='.'+s;
filename='DTN_full.csv';

// header is important as it as the image name
headersize=3;
blocksize=200;
C1=1;
C2=14;
iblock=1

// let save everything. Good for the example.
bigstruct = struct();

// Read all the value in one pass
// then using csvTextScan is much more efficient
text = mgetl(filepath+filename);

nlines = size(text,'r');
while ( %t )
  mprintf("Block #%d",iblock);
  // Lets read the header
  R1=(iblock-1)*(headersize+blocksize+1)+1;
  R2=R1 + headersize-1;
  // if R1 or R1 is bigger than the number of lines, stop
  if sum([R1,R2] > nlines )
      mprintf('; End of file\n')
      break
  end
  // We use csvTextScan ony on the lines that matters
  // speed the program, since csvRead read thge whole file
  // every time it is used.
  H=csvTextScan(text(R1:R2),",",".","string");
  mprintf("; %s",H(1,1))

  R1 = R1 + headersize;
  R2 = R1 + blocksize-1;

  if sum([R1,R2]> nlines )
      mprintf('; End of file\n')
      break
  end
  mprintf("; rows %d to %d\n",R1,R2)
  // Lets read the values
  V=csvTextScan(text(R1:R2),",",".","double");

  iblock=iblock+1
  // Let save theses data
  bigstruct(H(1,1)) = V;
end

和returns

Block #1; DTN-dist_0005_0; rows 4 to 203

....
Block #178; DTN-dist_0710_0; rows 36112 to 36311
Block #179; End of file
Time elapsed 1.827092s