Как создать последовательности с PDL? - PullRequest
3 голосов
/ 08 июля 2011

Я пытаюсь перевести часть моего R-кода в perl с помощью pdl, и я хотел бы знать, есть ли у pdl какой-либо синтаксис для создания последовательностей (кроме тривиального my $ xx = pdl (1..20))

что-то вроде наличия вектора ['a', 'b'] rep 20 => a, b, a, b, a, b .... 20 раз? [РЕДАКТИРОВАТЬ]: Основные повторения можно выполнить с помощью обычного оператора Perl string x, но я ищу что-то вроде rep () и seq () в R:

[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 ]

3 голосов
/ 21 апреля 2012

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, команды декодирования длин серий для выполнения операции rep вектора. Было бы просто реализовать подпрограммы R с использованием этих видов манипулирования индексами и измерениями. Кроме того, вышесказанное в основном работает с целочисленными индексными операциями. Если вам нужна поддержка чисел с плавающей запятой, вам нужно заняться чем-то другим.

См. PDL::Basic для последовательности вещей и PDL::Slices для манипуляций с индексами (PDL::NiceSlice также имеет значение, так как это синтаксис, использованный выше). Это легко попробовать, используя один из оболочек PDL: perldl или pdl2.

.

Веб-сайт PDL находится по адресу http://pdl.perl.org. Для получения дополнительной информации о PDL, пожалуйста, используйте список рассылки perldl для более быстрого ответа со стороны сообщества PDL в целом.

3 голосов
/ 24 сентября 2011

Ну, я только начал использовать PDL, но из того, что я видел и использовал, не похоже, что PDL действительно то, что вы хотите для создания последовательностей.Возможно, вам лучше использовать оператор диапазона Perl (..) с любой комбинацией map, grep и x.

Тем не менее, если вы действительно решили использовать 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 для создания ваших последовательностей.

[править] Вот как вы это сделаетечто: Обратите внимание, что 'x' не просто строковый множитель, он также умножает списки.Вам нужно явно использовать скобки вокруг ваших переменных, чтобы сообщить 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])
3 голосов
/ 08 июля 2011

Я не знаю ни о каком синтаксисе, специфичном для PDL, но с Perl вы можете использовать оператор x для повторения элементов списка. Может быть

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

будет работать.

1 голос
/ 30 января 2016

Вот несколько интересных вещей о функции 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]
1 голос
/ 24 сентября 2011

Как уже говорили другие люди, может быть проще сделать некоторые из ваших примеров с использованием Perl и передать его конструктору pdl. Однако последний пример достаточно прост:

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

После небольшой работы, не зная R, мне интересно, правильно ли сформулирован вопрос? Я начал предполагать, что вход для какой-то новой функции pdl_rep будет базовым piddle, а затем некоторой спецификацией повторения. Однако я начал сомневаться в том, что он должен делать, когда базовая опора имела более высокое измерение, чем простой вектор. Поэтому я остановился только на одномерном вводе. Затем я понял, что, как я и другие говорили, чтобы выполнить действие типа c или each, нужно разбить базовую опору и манипулировать элементами на уровне Perl и перестроить опору, или сделать глупое измерение манипуляция. Результатом всего этого было то, что казалось, что самый простой способ создать такую ​​функцию - это иметь сам конструктор pdl.

Как только этот вывод был сделан, я понял, что на самом деле сборка вашего piddle из хорошо сконструированных картографических операций - это то, что вы намерены делать. Предполагается, что PDL использует преимущества Perl, в противном случае это будет отдельный язык. Эта rep функция, возможно, не была реализована дизайнерами, потому что в Perl она уже есть в пиках.

Вероятно, TL; DR, но я думаю, что ваш краткий ответ - позволить вашему PDL использовать выгоду и от Perl!

...