【问题标题】:Wrapper for the matlab to read sparse data filematlab 读取稀疏数据文件的包装器
【发布时间】:2015-08-23 00:07:22
【问题描述】:

Libsvm 可以读取以下数据文件并将其转换为 matlab 中的稀疏数据结构(使用 libsvmread)。

-1 3:1 11:1 14:1 19:1 39:1 42:1 55:1 64:1 67:1 73:1 75:1 76:1 80:1 83:1 
-1 3:1 6:1 17:1 27:1 35:1 40:1 57:1 63:1 69:1 73:1 74:1 76:1 81:1 103:1 

第一列是二元分类的标签,其他列是特征向量。例如,在第一列中,只有位置 3,11,14,19... 不是零。

我有一个文件,其中这些位置没有排序。例如,它可能像 -

-1 11:1 3:1 14:1 19:1 39:1 42:1 55:1 64:1 67:1 73:1 75:1 76:1 80:1 83:1 

Libsvmread 在这种情况下将无法工作。无论如何,我可以在哪里对数据进行排序(根据位置),或者是否有任何现有代码可以帮助我在 matlab 中提取这些数据?

目标是给定这个样本输入

-1 11:1 3:1 14:1 19:1 39:1 42:1 55:1 64:1 67:1 73:1 75:1 76:1 80:1 83:1 
-1 3:1 2:1 6:1 4:1 17:1 27:1 35:1 40:1 57:1 63:1 69:1 73:1 74:1 76:1 81:1 103:1

我们得到以下输出:

-1 3:1 11:1 14:1 19:1 39:1 42:1 55:1 64:1 67:1 73:1 75:1 76:1 80:1 83:1
-1 2:1 3:1 4:1 6:1 17:1 27:1 35:1 40:1 57:1 63:1 69:1 73:1 74:1 76:1 81:1 103:1

【问题讨论】:

  • 从此-1 11:1 3:1 14:1 19:1 39:1 42:1 55:1 64:1 67:1 73:1 75:1 76:1 80: 1 83:1 至 -1 3:1 11:1 14:1 19:1 39:1 42:1 55:1 64:1 67:1 73:1 75:1 76:1 80:1 83:1
  • 使用此信息编辑您的问题,不要将其添加到评论中
  • 我正在尝试使用 awk(不太熟悉)。我记下了文本文件中的所有列并将它们分别存储,然后试图以某种方式对它们进行排序。另一件事是更改 libsvm 代码本身。

标签: matlab sorting text awk libsvm


【解决方案1】:

虽然我喜欢 awk 的答案,但还有另一个适合您的设置。

while read line; do echo $line | tr ' ' '\n' | sort -n | tr '\n' ' '; echo ""; done < inputfile

也就是将行转置为列并使用排序,然后再次转置;根据给定的格式,第一个元素将预先按数字排序。

【讨论】:

    【解决方案2】:

    将所有信息存储在数组a[] 中,然后使用索引进行排序:

    awk '{delete a
          for (i=2; i<=NF; i++) 
              a[$i+0]=$i
          n=asorti(a, sorted, "@ind_num_asc")
          printf "%s%s", $1, OFS
          for (i=1;i<=n;i++)
              printf "%s%s", a[sorted[i]], (i==n?ORS:OFS)}' file
    

    说明

    这使用asorti()@ind_num_asc 来定义排序模式。

    对于每一行,我们将所有从第二个字段开始的数据存储在一个数组a[] 中。然后,我们将其按数字排序并按排序顺序打印回来。

    • delete a 删除数组,这样我们就可以从这一行追加数据。
    • for (i=2; i&lt;=NF; i++) a[$i+0]=$i 将每个字段存储为数组中的一个元素。通过说$i+0,我们将xx:yy 转换为xx,这样索引就只是字段的左侧部分。
    • n=asorti(a, sorted, "@ind_num_asc") 使用其索引对数组进行排序并将其存储在sorted[] 数组中。通过说@ind_num_asc,我们告诉asorti 使用索引、数字和升序。
    • printf "%s%s", $1, OFS 打印第一个字段,即单独的字段。
    • for (i=1;i&lt;=n;i++) printf "%s%s", a[sorted[i]], (i==n?ORS:OFS) 循环遍历排序的值并打印它们。

    测试

    $ awk '{delete a; for (i=2; i<=NF; i++) {a[$i+0]=$i}; n=asorti(a, sorted, "@ind_num_asc"); printf "%s%s", $1, OFS; for (i=1;i<=n;i++) printf "%s%s", a[sorted[i]], (i==n?ORS:OFS)}' a
    1 3:1 11:1 14:1 19:1 39:1 42:1 55:1 64:1 67:1 73:1 75:1 76:1 80:1 83:1
    -1 2:1 3:1 4:1 6:1 17:1 27:1 35:1 40:1 57:1 63:1 69:1 73:1 74:1 76:1 81:1 103:1
    

    【讨论】:

    • 您好,非常感谢您的快速回答。但是当文本中有一行时,这有效。当有多行时,代码给出的答案非常不同。
    • 从您的问题中,我了解到数据仅在一行上。所以你有多行,你必须对每一行进行排序?然后请提供一组更相关的数据
    • @user3727929 查看更新。我确实完全重构了。检查它是否有效,然后我可以更新一些解释
    • 对不起,如果我问了一个愚蠢的问题,但是如何将文件的内容存储到数组中? asorti 是 awk 中的预定义函数吗?
    • asorti() 在 GNU awks 中。您可以通过说awk --version 来检查您是否属于这种情况。此外,您不必担心这些见解,因为awk 处理所有这些。只需使用您在问题中提到的格式将数据存储在文件中并运行此代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-05
    • 2015-05-29
    • 2015-09-02
    • 2017-08-27
    • 2012-06-20
    • 2012-01-03
    • 1970-01-01
    相关资源
    最近更新 更多