【问题标题】:Loading text data in Octave with specific format以特定格式在 Octave 中加载文本数据
【发布时间】:2014-09-28 15:50:12
【问题描述】:

我有一个数据集,我想存储并能够在 Octave 中加载

18.0   8   307.0      130.0      3504.      12.0   70  1    "chevrolet chevelle malibu"
15.0   8   350.0      165.0      3693.      11.5   70  1    "buick skylark 320"
18.0   8   318.0      150.0      3436.      11.0   70  1    "plymouth satellite"
16.0   8   304.0      150.0      3433.      12.0   70  1    "amc rebel sst"
17.0   8   302.0      140.0      3449.      10.5   70  1    "ford torino"
15.0   8   429.0      198.0      4341.      10.0   70  1    "ford galaxie 500"
14.0   8   454.0      220.0      4354.       9.0   70  1    "chevrolet impala"
14.0   8   440.0      215.0      4312.       8.5   70  1    "plymouth fury iii"
14.0   8   455.0      225.0      4425.      10.0   70  1    "pontiac catalina"
15.0   8   390.0      190.0      3850.       8.5   70  1    "amc ambassador dpl"

当我尝试使用时它不会立即起作用:

data = load('auto.txt')

有没有办法从给定格式的文本文件中加载,或者我需要将其转换为例如

18.0,8,307.0,130.0,3504.0,12.0,70,1
...

编辑: 删除最后一行并修复“一半”数字,例如3504.-> 3504.0 然后使用:

data = load('-ascii','autocleaned.txt');

根据需要将数据加载到 Octave 中的矩阵中。

【问题讨论】:

  • 由于所有数据都在固定宽度的列中(最后一个字符串除外),您应该能够逐行读取它,使用fscanf 解码该行。实际上,您将使用编写它时使用的相同记录说明符(在 C 或 Fortran 中)或 fprintf 来读取它。
  • 我已经知道如何使用其csvnumpy 模块将其加载到Python,然后通过.mat 文件将其传输到Octave。结果是 1x10 struct array 有 9 个字段 - 8 个数字和 1 个字符串。如果您愿意,我可以将其发布为答案。
  • @hpaulj 有兴趣了解更多低级方法来执行此操作。目前清理输入文件并使用 load 对我来说已经足够了。但在某些情况下,您需要更多控制权。在这里,更专业的方法可能会派上用场。
  • 在 Octave 文档中进一步挖掘,我发现它确实有 dlmreadcsvreadfilereadtextreadtextscan。除了dlmread 之外的所有内容都被解释并且可以使用type 读取。

标签: matlab io octave text-processing


【解决方案1】:

load 通常用于加载 octave 和 matlab 二进制文件,但也可用于加载像您这样的文本数据。您可以使用"-ascii" 选项加载数据,但即使启用了"-ascii" 选项,您也必须稍微重新格式化文件才能将其放入load。使用一致的列分隔符,即。只是一个制表符或一个逗号,使用完整的数字而不是 3850.,并且不要使用字符串。

然后你可以做这样的事情来让它工作

DATA = load("-ascii", "auto.txt");

【讨论】:

    【解决方案2】:

    如果从每一行中删除最后的字符串字段,则可以使用以下命令读取文件:

    filename='stack25148040_1.txt'
    fid = fopen(filename, 'r');
    [x, count] = fscanf(fid, '%f', [10, Inf])
    endif
    fclose(fid);
    

    或者,整个文件可以作为一列读入并重新整形。

    我还没有弄清楚如何读取数字字段和字符串字段。为此,我不得不依靠 Python 使用更通用的文件读取工具。

    这是一个 Python 脚本,它读取文件,创建 numpy 结构化数组,将其写入 .mat 文件,然后 Octave 可以读取该文件:

    import csv
    import numpy as np
    
    data=[]
    with open('stack25148040.txt','rb') as f:
        r = csv.reader(f, delimiter=' ')
        # csv handles quoted strings with white space
        for l in r:
            # remove empty strings from the split on ' '
            data.append([x for x in l if x])
    print data[0]
    for dd in data:
        # convert 8 of the strings (per line) to float
        dd[:]=[float(d) for d in dd[:8]]+dd[-1:]
    
    data=data[:-1]  # remove empty last line
    print data[0]
    print
    # make a structured array, with numbers and a string
    dt=np.dtype("f8,i4,f8,f8,f8,f8,i4,i4,|S25")
    A=np.array([tuple(d) for d in data],dtype=dt)
    print A
    from scipy.io import savemat
    savemat('stack25148040.mat',{'A':A})
    

    Octave 中可以使用

    load stack25148040.mat
    A
    # A = 1x10 struct array containing the fields:
    #    f0 f1 ... f8
    
    A.f8  # string field
    A(1)  # 1st row
    #  scalar structure containing the fields:
    #   f0 =  18
    #   f1 = 8
    ...
    #   f8 = chevrolet chevelle malibu
    

    较新的 Octave (3.8) 具有 importdata 函数。它无需任何额外参数即可处理原始数据文件。它返回一个包含 2 个字段的结构

    x.data 是一个(10,11) 矩阵。 x.data(:,1:8) 是所需的数值数据。 x.data(:,9:11)NA 和随机数的组合。 NA 代表行尾的单词。 x.textdata 是带有这些单词的 (24,1) 单元格。可以从这些单词中重新组合带引号的字符串 s,使用 NA 和引号来确定有多少单词属于哪一行。

    要读取它使用dlmread 的数字数据。由于importdata 的其余部分是用Octave 编写的,因此可以将其用作正确处理字符串数据的自定义函数的起点。

    dlmread ('stack25148040.txt')(:,1:8)
    importread ('stack25148040.txt').data(:,1:8)
    textread ('stack25148040.txt','')(:,1:8)
    

    【讨论】:

      【解决方案3】:

      https://octave.org/doc/v4.0.0/Simple-File-I_002fO.html

      试试这个,

      data = importdata('Auto.data')
      

      【讨论】:

        猜你喜欢
        • 2023-03-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多