我已经创建了一个PDL矩阵。我需要在每一行之间进行成对比较。目前,我使用'where‘和'cov’命令返回两个切片的成对比较(在perl循环中生成)。
我的问题是:如何使用“range”和“slice”以成对的方式遍历各行?如何返回我的索引位置?我已经使用perl遍历了矩阵。我读到过,使用perl进行循环确实会削弱PDL的功能。
所需输出:
indexA indexB Value
pos1 pos5 1
pos1 pos6 5
pos1 pos0 7 需要说明的是,我只想使用PDL功能。
这里有一些伪代码,可以(希望)更好地说明我的观点。
p $b
[
[1 0 3 0]
[0 1 0 1]
[1 3 1 3] <- example piddle y
[0 1 0 1] <- example piddle z
]
my concept function{
slice $b (grab row z) - works fine
slice $b (grab row y) - works fine
($a, $b) = where($a,$b, $a < 3 && $b < 3 ) - works fine
p $a [1 1]
p $b [0 0]
cov($a $b) - works just fine.
}我只需要一种在所有行上成对执行的方法。我需要做阶乘(n行)比较。
发布于 2012-04-22 03:00:12
PDL线程是你在这里寻找的概念。沿着维度循环的一般技术是在适当的位置添加虚拟维度,以便计算生成所需的隐式线程循环。对于多维问题,可以有许多不同的方法来添加dims,从而创建线程循环。
对于成对行计算,您可以选择两个嵌套循环,而不是切片索引,后者在两个索引计数上具有perl循环,并将沿着行生成PDL线程。您可以在索引上只使用一次perl循环,但利用隐式线程循环来一次计算所有行。
完全PDL线程循环计算将为每个参数的行上的循环添加一个虚拟维度,以便一次计算整个N**2行计算。以下是一个形状4,3数组的示例,其计算是==运算符:
pdl> $b = floor(random(4,3)*5)
pdl> p $b
[
[0 4 3 3]
[3 3 4 2]
[4 0 1 4]
]
pdl> p $b(,*3)==$b(,,*3)
[
[
[1 1 1 1]
[0 0 0 0]
[0 0 0 0]
]
[
[0 0 0 0]
[1 1 1 1]
[0 0 0 0]
]
[
[0 0 0 0]
[0 0 0 0]
[1 1 1 1]
]
]结果是一个形状4,3,3,0维对应于成对计算得到的行,1维和2维对应于==操作中涉及的行索引。
如果您需要来自这些线程循环计算的索引值,或者需要用于这些线程循环计算之一的索引值,请使用x、y、z或axis生成一个具有对应于该数组轴的索引值的piddle。
pdl> p $b->xvals
[
[0 1 2 3]
[0 1 2 3]
[0 1 2 3]
]
pdl> p $b->yvals
[
[0 0 0 0]
[1 1 1 1]
[2 2 2 2]
]关于PDL线程的实现有很多细节(与Perl线程或POSIX线程不同)。我推荐perldl mailing list作为参考,并与其他PDL用户和开发人员进行讨论。此外,请参阅PDL Book的第一个在线草案,其中包含了更全面的PDL计算和线程。
发布于 2012-03-02 15:59:18
我认为您正在寻找的是一种方法,可以在数组中找到所有不同的行对,然后使用cov处理每对行。如果这是正确的,那么我没有听说过cov,快速搜索一下文档也没有什么帮助。然而,我可以说一些可能会有帮助的事情。
我认为您在放弃使用PDL代码时过于谨慎了,如果您所做的只是循环所有行对的索引并使用slice拉出这些行,那么使用Perl代码就可以了。下面的一些示例代码显示了这一点。
此外,你不能像那样调用where,因为$a < 3等都是piddles本身,布尔运算符不会在它们上做你想做的事情。请改用&操作符,并添加一些括号以确保以正确的顺序执行表达式。
除此之外,我也无能为力,除非您纠正我对您的问题的理解,或者将我引向cov子例程的一些文档。
use strict;
use warnings;
use PDL;
my $dat = pdl <<END;
[
[1 0 3 0]
[0 1 0 1]
[1 3 1 3]
[0 1 0 1]
]
END
my $max2 = $dat->dim(1) - 1;
for my $i (0 .. $max2 - 1) {
for my $j ($i + 1 .. $max2) {
my $row1 = $dat->slice(",($i)");
my $row2 = $dat->slice(",($j)");
($row1, $row2) = where($row1, $row2, ($row1 < 3) & ($row2 < 3));
cov($row1, $row2);
}
}https://stackoverflow.com/questions/8595244
复制相似问题