【问题标题】:Splitting a large libsvm formatted file with command line tools使用命令行工具拆分大型 libsvm 格式文件
【发布时间】:2013-11-14 09:35:21
【问题描述】:

我有一个非常大的 libsvm 格式文件 (150GB),其中每一行如下所示:

-1 430018:1 429765:1 428103:1 428954:1 430172:1 427300:1 429485:1 432367:1 427059:1 426870:1 426556:2

(第一个标记是标签,其他标记是特征:值对)。

我用 Python 写了一个程序,把它转换成 [label, [array of feature ids], [array of values]] 如:

[-1, [430018,429765,428103,...], [1,1,1,...]]

但它在 Python 中运行速度极慢(我只能在 3 小时内处理 10GB 文件)。

有没有办法获取这个文件并将格式更改为每行 [label, [array of feature ids], [array of values]] 并将其写入另一个文件?

作为参考,这是我编写的用于转换每一行的 Python 脚本:

def convert(f, line)
        l = line.strip().split(" ")
        label = int(l[0])
        x = [map(int, f.split(":")) for f in l[1:]]
        x_idx, x_val = zip(*x)
        f.write(str([label, x_idx, x_val])+"\n")

【问题讨论】:

  • 只是为了确认一下,如果f在params中只是转换一个文件指针?
  • 请问这之后数据会怎样?我不禁想知道是否更像字典,例如对每个特征的值进行计数或求和可能更有用?
  • @ChrisProsser 实际上在我的原始代码中我没有发送 f 作为参数,我从函数返回 x_idx、x_val、标签并写入 main 中的文件。为了完整的代码,我只是将 f 添加到函数参数中。
  • @ChrisProsser 之后,我需要根据索引和值对对每一行执行一些数学运算。所以在我的代码中,我真正需要的是在单独的数组中获取 x_idx, x_val。我在执行数学更新时每行都在做这个解析,但这会使我的代码变慢。所以现在我想先进行这一行处理/分离,然后我可以每行读取已经解析的数组。我认为(希望)它会更快:)
  • 这里有一个真正的问题。但它需要工作。请向我们展示代码,您正在使用的真实代码,而不是“为了完整起见”的代码。看来您一次只处理一行,这可以加快很多。

标签: python command-line sed awk bigdata


【解决方案1】:
sed -u --posix "
s/^\([^ ]*\) \{1,\}\(.*\)$/[\1,[,\2 ][/
:peer
s/,\([[:digit:]]\{1,\}\):\([[:digit:]]\{1,\}\) \(.*\)$/,\1,\3,\2/
t peer
s/\[,/[/g
s/,]/]/g
s/$/]/
" yourfile

-u 对这种巨大的文件是强制性的。 --posix 用于 GNU sed

-i 如果直接修改,如果不重定向。

我不知道此类文件的性能。如果太慢,will 仍然可以尝试其他更高效的 sed,但可能更难定义。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-02-04
    • 1970-01-01
    • 2017-03-16
    • 1970-01-01
    • 1970-01-01
    • 2010-12-17
    • 2021-03-01
    相关资源
    最近更新 更多