如何用pdl创建序列?

时间:2011-07-08 16:28:14

标签: perl r pdl

我试图用pdl将我的部分R代码翻译成perl,我想知道pdl是否有任何创建序列的语法(除了琐碎的我的$ 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

5 个答案:

答案 0 :(得分:3)

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

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

会起作用。

答案 1 :(得分:3)

好吧,我刚刚开始使用PDL,但是从我所看到和使用的内容来看,似乎PDL并不像你想要的那样制作序列。您最好使用perl的范围运算符(..)与mapgrepx的任意组合。

那就是说,如果你因某种原因决定使用PDL,你可以使用sequence函数,然后旋转小提琴直到看起来像你想要的那样:

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]

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

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

[edit]以下是你如何做到这一点: 请注意,“x”不仅仅是字符串乘数,它还会使列表倍增。您需要在vars周围明确使用括号,以告知perl列表中正在使用x

#> 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])

答案 2 :(得分:3)

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

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

带有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,run length decode命令来执行向量rep操作。使用这些索引和维度操作来实现R例程将是直截了当的。此外,以上主要用于整数索引操作。如果您需要支持浮点数,则需要执行其他操作。

有关序列内容,请参阅PDL::Basic;有关索引操作,请参阅PDL::SlicesPDL::NiceSlice也是相关的,因为这是上面使用的语法)。很容易尝试使用其中一个PDL shell进行工作:perldlpdl2

PDL网站位于http://pdl.perl.org。有关PDL的更多讨论,请使用perldl mailing list以便PDL社区更快地做出响应。

答案 3 :(得分:1)

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

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

经过一番努力,不知道R,我想知道问题是否形成良好?我开始假设一些新的pdl_rep函数的输入将是一个基本的,然后是一些重复规范。然而,我开始怀疑自己应该做什么,当基础小提琴比一个简单的向量更高。因此我只选择1D输入。然后我意识到,正如我和其他人所说的那样,要做ceach类型的动作,必须拆分基本的小提琴并操纵Perl级别的元素并重建一个小提琴,否则做一些愚蠢的尺寸操纵。所有这一切的结果是,似乎构建这样一个函数的最简单方法是让它本身就是一个pdl构造函数。

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

可能是TL; DR,但我认为你的简短回答是让你的PDL也从Perl中受益!

答案 4 :(得分: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]