Как создать последовательности с PDL?

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

что-то вроде наличия вектора ['a','b'] rep 20 => a,b,a,b,a,b.... 20 раз?[РЕДАКТИРОВАТЬ]: Основные повторения могут быть сделаны с обычной строкой повторения Perl 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 ответов

Решение

Ну, я только начал использовать 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]

(Выше было бы короче, если бы я знал, как проще дублировать матрицы) [править] Кажется, что это легко сделать с помощью фиктивной фигуры!$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])

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

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

должно сработать.

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.

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

Как говорили другие люди, может быть проще сделать некоторые из ваших примеров с использованием 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!

Другие вопросы по тегам