【问题标题】:What's the equivalent of R's ifelse in Perl PDLPerl PDL 中 R 的 ifelse 等价物是什么
【发布时间】:2018-07-11 21:26:54
【问题描述】:

我是 PDL 的新手。 R 的 ifelse() 方法可以进行条件元素选择。例如,

x <- c(1,2,3,4)
ifelse(x%%2, x, x*2)
# [1] 1 4 3 8

有人知道如何在 PDL 中执行此操作吗?我知道你可以像下面那样做,但是有没有更好的方法?

pdl(map { $_ % 2 ? $_ : $_*2 } @{$x->unpdl} )

【问题讨论】:

    标签: r perl pdl


    【解决方案1】:
    #! /usr/bin/perl
    use warnings;
    use strict;
    
    use PDL;
    
    my $x     = 'PDL'->new([1, 2, 3, 4]);
    my $where = ! ($x % 2);               # [0 1 0 1]
    my $y     = $x * ($where + 1);
    print $y;                             # [1 4 3 8]
    

    或者,很快

    my $y = $x * ( 2 - $x % 2 );
    

    【讨论】:

    • 对不起,我不是在问如何解决那个特定的例子。我实际上是在寻求一种通用的抽象方式,比如 R 的 ifelse() 方法。
    【解决方案2】:

    自己回答问题。可以是这样的,

    use PDL;                                                                      
    
    sub ifelse {                                                                  
        my ( $test, $yes, $no ) = @_;                                             
    
        $test = pdl($test);                                                       
        my ( $ok, $nok ) = which_both($test);                                     
    
        my $rslt = zeros( $test->dim(0) );                                        
    
        unless ( $ok->isempty ) {                                                 
            $yes = pdl($yes);                                                     
            $rslt->slice($ok) .= $yes->index( $ok % $yes->dim(0) );               
        }                                                                         
        unless ( $nok->isempty ) {                                                
            $no = pdl($no);                                                       
            $rslt->slice($nok) .= $no->index( $nok % $no->dim(0) );               
        }                                                                         
        return $rslt;                                                             
    }                                                                             
    
    my $x = pdl( 1, 2, 3, 4 );                                                    
    say ifelse( $x % 2, $x, $x * 2 );       # [1 4 3 8]                                             
    say ifelse( $x % 2, 5, sequence( 3 ) ); # [5 1 5 0]                                      
    say ifelse( 42, $x, $x * 2 );           # [1]
    

    【讨论】:

      【解决方案3】:

      $x ? $y : $z好吗?我不介意,但这是风格和品味的问题

      sub ifelse {
          my ($x,$y,$z) = @_;
      
          $x ? $y : $z ;
          if($x){$y}else{$z} ;
          [$y,$z]->[!$x] ;
          [$z,$y]->[!!$x] ;
          ($x && $y) || $z ;        # valid only if $y is always true
          (!$x && $z) || $y ;       # valid only if $z is always true
      }
      

      【讨论】:

      • 不,我不是在要求“普通”Perl。我要PDL。 $x?$y:$z 之类的东西不适用于 PDL。
      猜你喜欢
      • 2011-03-24
      • 2011-09-14
      • 2012-03-20
      • 2021-06-19
      • 2011-03-25
      • 2023-04-04
      • 2012-09-06
      • 1970-01-01
      • 2011-01-07
      相关资源
      最近更新 更多