matlab 读取稀疏数据文件的包装器

Wrapper for the matlab to read sparse data file

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

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

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

说明

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

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

  • delete a删除数组,这样我们就可以从这一行追加数据。
  • for (i=2; i<=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", , OFS 打印第一个字段,即单独的字段。
  • for (i=1;i<=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", , 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

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

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

也就是把行转列,排序,再转置;根据给定的格式,第一个元素将预先按数字排序。