Octave中如何以特定格式加载文本数据

7

我有一个数据集,希望能够存储并在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
...

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

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

在Octave中,将数据按照要求加载到一个矩阵中。


由于所有数据都在固定宽度的列中(除了最后的字符串),因此您应该能够逐行读取它,使用 fscanf 解码该行。实际上,您将使用相同的记录说明符(在 C 或 Fortran 中)或 fprintf 来读取它。 - hpaulj
我已经弄清楚了如何使用Pythoncsvnumpy模块将其加载,然后通过.mat文件将其传输到Octave。结果是一个1x10结构数组,其中有9个字段-8个数字和1个字符串。如果您愿意,我可以将其发布为答案。 - hpaulj
@hpaulj 很有趣了解更多低级别的方法来做这件事。目前清理输入文件并使用加载已经足够了。但是有些情况下,您可能需要更多的控制权。在这种情况下,更专业的方法可能会派上用场。 - user317706
1
深入研究Octave文档后,我发现它确实有dlmreadcsvreadfilereadtextreadtextscan。除了dlmread之外,所有这些函数都是解释型的,并且可以使用type进行读取。 - hpaulj
3个回答

8
load通常用于加载Octave和Matlab二进制文件,但也可以用于加载像您这样的文本数据。您可以使用"-ascii"选项加载数据,但是在启用"-ascii"选项后,您需要稍微重新格式化文件才能将其放入load中。请使用一致的列分隔符,即一个制表符或逗号,使用完整数字而不是3850. ,也不要使用字符串。
然后,您可以执行类似以下内容的操作以使其正常工作。
DATA = load("-ascii", "auto.txt");

6

如果每行中的最后一个字符串字段被删除,可以使用以下方式读取文件:

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) 的单元格,包含这些单词。可以使用 NA 和引号确定哪些词属于哪一行,从而重新组装字符串 s。为读取数字数据,它使用 dlmread。由于 importdata 的其余部分是用 Octave 编写的,因此可以将其用作自定义函数的起点,以正确处理字符串数据。
dlmread ('stack25148040.txt')(:,1:8)
importread ('stack25148040.txt').data(:,1:8)
textread ('stack25148040.txt','')(:,1:8)

2
最初的回答:请尝试以下操作,

点击这里

data = importdata('Auto.data')

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接