I believe that the code below modifies $x in place, but I'm not too familiar with the internals of PDL. There is a problem with the code below; for elements equal to 0, it will replace all of those elements with the same result...which may not be what you want.
#!/usr/bin/env perl
use strict;
use warnings;
use PDL;
use PDL::NiceSlice;
my $x = pdl(0,4,0,-3);
print "Before: $x\n";
$x(which($x > 0)) .= 1;
$x(which($x < 0)) .= 0;
$x(which($x == 0)) .= int(rand(9)) > 5 ? 1: 0;
print "After: $x\n";
exit;
The code below will fix that problem, but you need to iterate through each element of the pdl:
#!/usr/bin/env perl
use strict;
use warnings;
use PDL;
my $x = pdl(0,4,0,-3);
print "Before: $x\n";
my $n = nelem($x);
for ( my $i = 0; $i < $n; ++$i ) {
my $val = $x->index($i);
$val = $val > 0 ? 1 :
$val < 0 ? 0 :
$val == 0 ? (int(rand(9)) > 5 ? 1 : 0) : undef;
$x->index($i) .= $val;
}
print "After: $x\n";
exit;
By the way, you may find this node helpful: Processing values of a piddle (PDL) speedup using 'at' vs. 'index'. It's a discussion related to processing the elements of a pdl individually. In general, it's a good idea to avoid processing the elements individually (i.e. it's likely better if you can find a way to use the vector operations of PDL). If you can not avoid processing the elements individually, you may want to consider exporting the pdl to a perl array, performing some operations on the values of the array, and then creating a pdl from the result.
I took a quick looked around for the pdl equivalent of the map command but I did not find one. |