4

我试图用 pdl 将我的部分 R 代码翻译成 perl,我想知道 pdl 是否有任何用于创建序列的语法(除了琐碎的 my $xx=pdl(1..20))

比如有一个向量 ['a','b'] rep 20 => a,b,a,b,a,b.... 20 次? [编辑]:基本的重复可以用普通的 Perl 重复字符串x运算符来完成,但我正在寻找 R 中的 rep() 和 seq() 之类的东西:

[R]
> rep(1:3, each=2, times=3)
1 1 2 2 3 3 1 1 2 2 3 3 1 1 2 2 3 3
> rep(1:4, c(1,2,3,2))
1 2 2 3 3 3 4 4
> seq(0,12,3)
0 3 6 9 12
4

5 回答 5

3

我不知道任何特定于 PDL 的语法,但是使用 Perl,您可以使用x运算符来重复列表的元素。也许

$xx = pdl(  ('a','b') x 20   );

会工作。

于 2011-07-08T16:31:30.793 回答
3

好吧,我才刚刚开始使用 PDL,但从我所见和使用的情况来看,PDL 似乎并不是你真正想要的用于制作序列的东西。您最好将 perl 的范围运算符 ( ..) 与 、 和 . 的任意组合map一起grep使用x

也就是说,如果您出于某种原因真的决定使用 PDL,您可能可以使用该sequence函数,然后旋转 piddle 直到它看起来像您想要的那样:

pdl> p sequence(10)

[0 1 2 3 4 5 6 7 8 9]


pdl> p sequence(2,4) #Slice column 1 for evens, 2 for odds.

[
 [0 1]
 [2 3]
 [4 5]
 [6 7]
]


pdl> p sequence(3,4) * 5 #Multiply to step by an amount.

[
 [ 0  5 10]
 [15 20 25]
 [30 35 40]
 [45 50 55]
]

您还可以使用切片来抓取列,以此作为沿着序列步进的一种方式。

对于其他任何事情,例如您在 R 示例中所做的事情,您需要开始发挥创意:

pdl> p $a = (yvals zeroes(2,3))+1

[
 [1 1]
 [2 2]
 [3 3]
]

pdl> p pdl($a,$a,$a)->flat #-> rep(1:3, each=2, times=3)
[1 1 2 2 3 3 1 1 2 2 3 3 1 1 2 2 3 3]

(如果我知道如何更容易地复制矩阵,上面的内容会更短)[编辑] 看起来很容易用 dummy 完成! $a = (zeroes(2,3)->yvals + 1)->dummy(2,3)->flat

再一次,除非您有特殊需要这样做,否则我认为最好使用 perl 来制作您的序列。

[编辑]您可以这样做:注意 ' x' 不只是一个字符串乘法器,它还乘以列表。您需要在变量周围显式使用方括号来通知 perlx正在列表中使用。

#> rep(1:3, each=2, times=3)
my @s = map {($_) x 2} (1..3) x 3;

#> seq(0,12,3)
my @s = map {$_ * 3} 0..12/3;

#> rep(1:4, c(1,2,3,2))
#Ewww. So you basically want to multiply one list by another list.
#Here's one way to do it:
use List::MoreUtils qw(pairwise);
my @s = &pairwise(sub {($a) x $b}, [1..4], [1,2,3,2])
于 2011-09-24T12:20:38.313 回答
3

PDL 没有seq()rep()具体来说,但它确实具有构造函数以及操作和重塑多维数据的能力。

具体来说,复制序列可以通过将这些大小的虚拟维度添加到原始数据中,然后将结果重新整形为一维来完成。

具有 start:stop:stride 的序列可以通过对整数序列的算术运算生成,该整数序列可以使用 sequence() 构造函数生成。

以下是一些 PDL 版本,它们对应于原始问题中的两个 R 片段,并带有解释对应关系的注释:

pdl> pdl(1..3)                  # 1:3
$PDL1 = [1 2 3];

pdl> pdl(1..3)->(*2)->flat      # rep(1:3, each=2)
$PDL1 = [1 1 2 2 3 3];

pdl> pdl(1..3)->(,*3)->flat     # rep(1:3, times=3)
$PDL1 = [1 2 3 1 2 3 1 2 3];

pdl> pdl(1..3)->(*2,,*3)->flat  # rep(1:3, each=2, times=3)
$PDL1 = [1 1 2 2 3 3 1 1 2 2 3 3 1 1 2 2 3 3];

pdl> rld(pdl(2,1,5),pdl(1..3))  # rep(1:3, c(2,1,5))
$PDL1 = [1 1 2 3 3 3 3 3];


pdl> sequence(13)->(0:12:3)     # seq(0,12,3)
$PDL1 = [0 3 6 9 12];

注意使用rld运行长度解码命令来执行向量rep操作。使用这些类型的索引和维度操作来实现 R 例程将很简单。此外,上述内容主要适用于整数索引操作。如果您需要对浮点数的支持,则需要执行其他操作。

有关PDL::Basic序列的内容和PDL::Slices索引操作,请参阅(PDL::NiceSlice也与上面使用的语法相关)。使用其中一个 PDL shell 可以很容易地尝试这种事情:perldlpdl2.

PDL 网站位于http://pdl.perl.org。有关 PDL 的更多讨论,请使用perldl 邮件列表,以便整个 PDL 社区更快地响应。

于 2012-04-20T21:58:28.353 回答
1

正如其他人所说,使用 Perl 做一些示例并将其传递给pdl构造函数可能更容易。但是最后一个例子很简单:

$x = 3*xvals(5);
print $x; # [0 3 6 9 12]

经过一些工作,并且不知道 R,我想知道这个问题是否形成良好?我开始假设一些新pdl_rep函数的输入将是一个基本的 piddle,然后是一些重复规范。但是,当基本 piddle 的维度高于简单向量时,我开始怀疑自己应该做什么。因此我只选择了一维输入。然后我意识到,正如我和其他人所说,要执行cor eachtype 操作,必须分解基本 piddle 并在 Perl 级别操作元素并重建 piddle,否则进行一些愚蠢的维度操作。所有这一切的结果是,构建这样一个函数的最简单方法似乎就是让它本身成为一个 pdl 构造函数。

一旦得出这个结论,我就意识到,从构建良好的地图操作中构建你的 piddle 确实是你打算做的。PDL 旨在从 Perl 的强大功能中受益,否则它将是一门单独的语言。这个rep功能可能没有被设计者实现,因为 Perl 已经有了它。

可能是 TL;DR,但我认为您的简短回答是让您的 PDL 使用也受益于 Perl!

于 2011-09-24T13:54:09.137 回答
1

下面是关于 sequence() 函数和矩阵的一些有趣的事情

$x = sequence(20)*2+1; ##odd
[1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39]
$x = sequence(20)*2;  ##even 
[0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38]
$x = sequence(20)%2; ## binary pattern
[0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1]
$x = sequence(20)%10  ## position matrix
[0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9]
$x = sequence(20)<=>10;  ## ray matrix
[-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 0 1 1 1 1 1 1 1 1 1]
$x = sequence(20)%4+2;  ## repeating pattern
[2 3 4 5 2 3 4 5 2 3 4 5 2 3 4 5 2 3 4 5]
$x = sequence(20)%6;  ##  notice how this is different 
[0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1]
于 2016-01-30T10:01:24.487 回答