假设我有两个双精度数组.我一直在试验 Java 8 中的 Stream.我想我已经理解了主要思想但后来我意识到我不确定如何同时操作两个流.
Let's say I have two arrays of double. I've been experimenting with Stream from Java 8. I think I've understood the main ideas but then I realised that I'm not sure how to manipulate two Streams at the same time.
例如,我想计算两个数组的协方差.
For example, I want to calculate the covariance of both arrays.
public class foo { public static double mean(double[] xs) { return Arrays.stream(xs).average().getAsDouble(); } public static void main(String[] args) { double[] xs = {1, 2, 3, 4, 5, 6, 7, 8, 9}; double[] ys = {1517.93, 1757.78, 1981.1, 2215.73, 2942.66, 3558.32, 4063.91, 4521.16, 5101.76, 5234.12}; System.out.println("Mean of xs: " + mean(xs)); double xs_sumDeviation = Arrays.stream(xs) .boxed() .mapToDouble(d -> d.doubleValue() - mean(xs)) .sum(); // Covariance double covXY = Arrays.stream(xs, ys) .mapToDouble(x,y -> { double numerator = (x-mean(xs)* (y-mean(ys); double denominator = Math.sqrt((x-mean(xs)* (x-mean(xs)); return numerator / denominator; }) .sum(); } }感谢您的建议.
尝试 1.
public static double covariance(double[] xs, double[] ys) { double xmean = mean(xs); double ymean = mean(ys); double numerator = IntStream.range(0, Math.min(xs.length, ys.length)) .parallel() .mapToDouble(i -> (xs[i] - xmean) * (ys[i] - ymean)) .sum(); double denominator = Math.sqrt(IntStream.range(0, xs.length) .parallel() .mapToDouble(i -> (xs[i] - xmean) * (xs[i] - xmean)) .sum()); return numerator / denominator; 推荐答案在其他编程语言中,有某种 zip 函数,它需要几个 iterables,并且返回一个 iterator,它聚合了每个 iterables 中的元素.例如,参见 Python 库中的 zip 函数.
In other programming languages, there is some kind of zip function, that takes several iterables, and returns an iterator that aggregates elements from each of the iterables. See for example the function zip in the Python Library.
尽管可以在 Java 中创建类似的函数,但很难以支持高效并行执行的方式实现它.但是,Java 中有一个常用的模式,它有点不同.在您的情况下,它可能如下所示:
Although it would be possible to make a similar function in Java, it's hard to implement it in such a way, that it supports efficient parallel execution. However, there is a commonly used pattern in Java, that is a bit different. In your case, it might look as follows:
public static double covariance(double[] xs, double[] ys) { double xmean = mean(xs); double ymean = mean(ys); return IntStream.range(0, Math.min(xs.length, ys.length)) .parallel() .mapToDouble(i -> { double numerator = (xs[i] - xmean) * (ys[i] - ymean); double denominator = ...; return numerator / denominator; }) .sum(); }不是组合两个流,而是创建一个带有所有索引的 IntStream,并通过索引访问不同集合的元素.只要集合支持随机访问操作,就可以很好地工作.
Instead of combining two streams, you create an IntStream with all indexes, and you access the elements of the different collections by index. That works pretty well as long as the collections support random access operations.
更多推荐
在 Java lambda 中使用两个流来计算协方差
发布评论