【问题标题】:How can I co-sort two Vecs based on the values in one of the Vecs?如何根据其中一个 Vecs 中的值对两个 Vecs 进行共同排序?
【发布时间】:2015-09-14 12:10:25
【问题描述】:

我有两个 Vecs 对应于特征向量列表及其对应的类标签,我想按类标签对它们进行共同排序。

然而,Rust 的 sort_by 在切片上运行,而不是作为 trait(或类似)上的通用函数,并且闭包只获取要比较的元素而不是索引,因此我可以偷偷地破解排序为并行。

我已经考虑过解决方案:

let mut both = data.iter().zip(labels.iter()).collect();
both.sort_by( blah blah );
// Now split them back into two vectors

我不希望每次都分配一个全新的向量来执行此操作,因为数据的大小可能非常大。

当然,我总是可以实现自己的排序,但如果有内置的方法可以做到这一点,那就更好了。

【问题讨论】:

  • @Shepmaster 我将它传递给 libsvm 这要求它们是分开的,所以很遗憾是的。
  • 一种最小化分配的方法是只分配一个索引向量(如果你的元素少于 40 亿,它们只需要u32,所以每个元素 4 个字节)并排序通过sort_by 索引到labels。然后可以使用结果将datalabels 置换为正确的顺序。 (当然,不幸的是仍然分配 O(n) 内存。)
  • sort_by 自己不做,你需要自己实现排序,可能以sort_by 为基础。哦,它不能只给你索引,因为它们不是恒定的。如果您真的要坚持使用sort_by,则需要进行指针比较以获取切片中元素的索引,然后弄清楚sort_by 将如何处理您的响应并将其用于其他向量自己,这将是一种完全疯狂和脆弱的方式。所以,是的,只要看看 sort_by 做了什么并复制它。
  • 请注意,sort_by 已经分配了 2n 个空间,因此除非您使用不同的排序函数,否则您不会避免分配。
  • [T]::sort/sort_by 是一个稳定的排序。如果您需要不稳定的非分配排序,在 crates.io 上还有其他选择。

标签: rust


【解决方案1】:

我刚刚写了a crate "permutation" 允许你这样做:)

let names = vec!["Bob", "Steve", "Jane"];
let salary = vec![10, 5, 15];
let permutation = permutation::sort(&salary);
let ordered_names = permutation.apply_slice(&names);
let ordered_salaries = permutation.apply_slice(&salary);
assert!(ordered_names == vec!["Steve", "Bob", "Jane"]);
assert!(ordered_salaries == vec![5, 10, 15]);

将来它可能会在单个函数调用中支持这一点。

【讨论】:

  • 感谢您为 Rust 社区做出贡献。就我而言,很遗憾这是根据 GPL 而不是 MIT / Apache 许可的,就像大多数 Rust 库一样。
  • 我已将许可证更新为在 Apache / MIT 下获得双重许可,就像 Rust 一样。
  • 不幸的是,这非常慢,因为应用排列现在涉及随机访问读取,而排序主要使用本地化内存访问。
  • @orlp 你有基准还是这只是猜测?
猜你喜欢
  • 2017-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多