【问题标题】:Reducing an array size by averaging通过平均减少数组大小
【发布时间】:2018-07-17 00:05:48
【问题描述】:

我有一个大的采样波形,我想通过将其重新采样(平均)到较低的速率来记录它的压缩版本以进行诊断。较低的利率将始终是原始利率的偶数除数。 例如:通过平均 8 个样本块将 32K 波形压缩为 4K 波形。

有没有使用 Linq/IEnumerable 的简单方法来做到这一点

【问题讨论】:

  • @Aybe 你什么意思?
  • 也许您的方法可能无法保留您认为有价值的信号特征,峰峰值幅度。考虑在Signal Processing Stack Exchange 询问(虽然我不能说那里的主题是什么)。
  • 我所要求的将实现我的意图。情况是我正在记录波形数字化仪(类似于示波器)的结果,我需要捕获另一个需要更快采样率的信号;但是,我希望当前记录的频道保持不变。我以前用过 Linq 做过类似的事情;但是,我不经常使用它,我想看看其他人如何实现结果。 CPU 时间可能不是一个因素。

标签: c# arrays linq compression ienumerable


【解决方案1】:

不是很纯的 Linq,但这会做到:

int divisor = 2;
int index = 0;
var cutSamples = samples
    .GroupBy(s => index++ / divisor)
    .Select(g => g.Average());

在性能方面,Linq 不是你的朋友,所以这会快得多:

public static double[] CutSamples(double[] samples, int divisor)
{
    var reducedSamples = new double[samples.Length / divisor];
    int reducedIndex = 0;
    for (int i = 0; i < samples.Length; i += divisor)
    {
        double sum = 0;
        int count = 0;
        for (int j = 0; j < divisor && (i + j) < samples.Length; j++)
        {
            sum += samples[i + j];
            count++;
        }

        reducedSamples[reducedIndex++] = sum / count;
    }

    return reducedSamples;
}

【讨论】:

  • 为什么说循环比 Linq 快?有没有关于这方面的研究/报告?
  • Linq 在性能上充其量与手写代码相当。大多数情况下它会变慢 - 有时会非常慢,就像在这种情况下一样。 GroupBy 是一个通用的东西,它根据一个键对元素进行分组。但是为了让它遍历任何组,它必须通过遍历每个项目并分配内存来实际构建每个组。这意味着它速度较慢,而且使用的内存要多得多。
  • 我建议你两个都试试,看看你更喜欢哪一个。对于较小的数组大小,Linq 版本会非常好。
猜你喜欢
  • 2015-07-01
  • 2014-12-25
  • 2016-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-08
  • 2014-10-17
  • 1970-01-01
相关资源
最近更新 更多