[英]Perl PDL : Search if a vector is in an array or in a matrix
我嘗試在 PDL 矩陣或 Vector 數組上制作 grep:
my @toto;
push(@toto, pdl(1,2,3));
push(@toto, pdl(4,5,6));
my $titi=pdl(1,2,3);
print("OK") if (grep { $_ eq $titi} @toto);
我也試過
my @toto;
push(@toto, pdl(1,2,3));
push(@toto, pdl(4,5,6));
my $titi=pdl(1,2,3);
print("OK") if (grep { $_ eq $titi} PDL::Matrix->pdl(\@toto));
沒有工作。
任何幫助請
免責聲明:我對PDL一無所知。 我已經閱讀了這個消息來源。
有一個函數PDL::all()
可以與重載的比較運算符==
一起使用。
use PDL;
my $foo = pdl(1,2,3);
my $bar = pdl(4,5,6);
my $qrr = pdl(1,2,3);
print "OK 1" if PDL::all( $foo == $bar );
print "OK 2" if PDL::all( $foo == $qrr );
我還在尋找文檔。
以可縮放的方式有效地執行此操作的方法是使用PDL::VectorValued::Utils和兩個 ndarray(“haystack”是一個 ndarray,而不是 Perl ndarray 數組)。 小的 function vv_in
沒有顯示為復制粘貼到perldl
CLI 中,因為從這個答案中復制粘貼它的可能性較小:
sub vv_in {
require PDL::VectorValued::Utils;
my ($needle, $haystack) = @_;
die "needle must have 1 dim less than haystack"
if $needle->ndims != $haystack->ndims - 1;
my $ign = $needle->dummy(1)->zeroes;
PDL::_vv_intersect_int($needle->dummy(1), $haystack, $ign, my $nc=PDL->null);
$nc;
}
pdl> p $titi = pdl(1,2,3)
[1 2 3]
pdl> p $toto = pdl([1,2,3], [4,5,6])
[
[1 2 3]
[4 5 6]
]
pdl> p $notin = pdl(7,8,9)
[7 8 9]
pdl> p vv_in($titi, $toto)
[1]
pdl> p vv_in($notin, $toto)
[0]
請注意,為了提高效率, $haystack
需要已經排序(使用qsortvec
)。 dummy
對象“膨脹” $needle
使其成為具有一個向量的向量集,然后vv_intersect
返回兩個 ndarray:
vectorlength,0
- 一個空的 ndarray) 使用“內部”( _vv_intersect_int
) 版本是因為從 PDL::VectorValued 1.0.15 開始,它有一些不允許廣播的包裝 Perl 代碼(已提交 問題)。
注意vv_in
將在多組輸入向量和輸入干草堆上“廣播”(以前稱為“線程”,令人困惑)。 這可用於搜索多個向量:
sub vv_in_multi {
my ($needles, $haystack) = @_;
die "needles must have same number of dims as haystack"
if $needles->ndims != $haystack->ndims;
vv_in($needles, $haystack->dummy(-1));
}
pdl> p vv_in_multi(pdl($titi,$notin), $toto)
[1 0]
感謝 Ed 上面的 VectorValued 大喊(以及錯誤報告)。 回想起來,我發現如果$toto
被排序(la qsortvec()
,就像在你的例子中一樣),你可以使用vsearchvec()
,也來自 PDL::VectorValued::Utils 並且通常更快比vv_intersect
(對數與線性):
sub vv_in_vsearch {
require PDL::VectorValued::Utils;
my ($needle, $haystack) = @_;
my $found = $needle->vsearchvec($haystack);
return all($haystack->dice_axis(1,$found) == $needle);
}
pdl> $titi = pdl(1,2,3)
pdl> $tata = pdl(4,5,6)
pdl> $toto = pdl([1,2,3], [4,5,6])
pdl> $notin = pdl(7,8,9)
pdl> p vv_in_vsearch($titi, $toto)
1
pdl> p vv_in_vsearch($tata, $toto)
1
pdl> p vv_in_vsearch($notin, $toto)
0
(完全披露:我編寫並維護 PDL::VectorValued)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.