我有一个一维PDL,我想对每一半进行计算;也就是说,将它分开,然后在前半部分进行计算,在下半部分进行相同的计算。
是否有一种更容易/更好/更优雅的方法来简单地将PDL分割成两半,而不是得到元素的数量(用nelem),然后将其除以二,然后执行两片呢?
谢谢
发布于 2013-11-22 14:24:26
是的,只要你不需要直接调用片来得到你想要的东西。您可以使用这样的方法来链接splitdim和dog:
# Assume we have $data, a piddle
my ($left, $right) = $data->splitdim(0, $data->nelem/2)->dog;当然,这很容易扩展到两个以上的部门。但是,如果您想将其扩展到更高维的小空间(即存储在一个小空间中的时间序列的集合),那么您就需要更加精细一些。如果您想沿着第一个维度(它的索引为0)分割,您可以这样说:
# Assume we have $data, a piddle
my ($left, $right) = $data->splitdim(0, $data->dim(0)/2)->mv(1, -1)->dog;splitdim操作将第0维分解为二维,第0维长度为dim(0)/2,第1维为2维(因为我们将其分为两部分)。由于dog在最后一个维度上操作,所以在调用dog之前,我们将第一个维度移到末尾。
然而,即使是单维解决方案,也有一个警告。由于$data->splitdim的工作方式,如果您有奇数的元素,它将截断最后一段数据。在一个有21个元素的凸起点上尝试一下这个操作,你就会明白我的意思:
my $data = sequence(20);
say "data is $data"; # lists 0-19
my ($left, $right) = $data->splitdim(0, $data->nelem/2)->dog;
say "left is $left and right is $right"; # lists 0-9, then 10-19
$data = sequence(21);
say "data is $data"; # lists 0-20, i.e. 21 elements
my ($left, $right) = $data->splitdim(0, $data->nelem/2)->dog;
say "left is $left and right is $right"; # lists 0-9, then 10-19!!如果您想要避免这种情况,您可以生成您自己的方法,将第一个维度分割成两半,而不需要截断。它可能看起来是这样的:
sub PDL::split_in_half {
my $self = shift;
# the int() isn't strictly necessary, but should make things a
# tad faster
my $left = $self->slice(':' . int($self->dim(0)/2-1) );
my $right = $self->slice(int($self->dim(0)/2) . ':');
return ($left, $right);
}在这里,我还使用了内置的int,以确保如果.5是奇怪的,我们就没有dim(0)。这有点复杂,但我们把这种复杂性精确地隐藏在一种方法中,这样我们就不需要考虑复杂性了,所以我们可以在它的同时为自己买几个时钟周期。
这样,您就可以轻松地调用该方法:
my ($left, $right) = $data->split_in_half;https://stackoverflow.com/questions/20128532
复制相似问题