如何用纯PDL实现同时统计两组浮点值的出现次数?
纯PDL实现两组浮点值的频次统计
我需要同时统计两组浮点值的配对出现次数,目前用哈希结合数组的方式实现,但这种方法运行耗时较长。想请教是否可以用纯PDL完成相同功能?
当前实现代码:
my @Key_Str = swcols "%0.2f_%0.2f", $a_datas, $b_datas; my %counts; foreach my $key_str (@Key_Str) { $counts{$key_str}++; } my (@p_a, @p_b, @cnts); foreach (sort keys %counts){ my ($z, $h) = split /_/, $_; push @p_a, $z; push @p_b, $h; push @cnts, $counts{$_}; } my $a= pdl(@p_a); my $b = pdl(@p_b); my $count = pdl(@cnts);
完整示例代码及运行结果:
示例代码:
#!/usr/bin/perl use PDL; use Data::Dumper; use feature 'say'; my $a_data = pdl(1.5, 2.1, 2.1, 1.5, -5.7); my $b_data = pdl(12.2, 22.3, 22.3, 12.2, 15.3); my @Key_Str = swcols "%0.2f_%0.2f", $a_data, $b_data; my %counts; foreach my $key_str (@Key_Str) { $counts{$key_str}++; } my (@p_a, @p_b, @cnts); foreach (sort keys %counts){ my ($z, $h) = split /_/, $_; push @p_a, $z; push @p_b, $h; push @cnts, $counts{$_}; } my $a= pdl(@p_a); my $b = pdl(@p_b); my $count = pdl(@cnts); say $a; say $b; say $count;
运行结果:
[-5.7 1.5 2.1] [15.3 12.2 22.3] [1 2 2]
可以用PDL的uniqvec和histogram方法实现纯PDL版本,避免Perl循环与哈希操作,提升处理效率。核心逻辑和原代码一致:先按两位小数精度量化数据,再统计配对频次,最后排序输出。
纯PDL实现代码:
#!/usr/bin/perl use PDL; use feature 'say'; my $a_data = pdl(1.5, 2.1, 2.1, 1.5, -5.7); my $b_data = pdl(12.2, 22.3, 22.3, 12.2, 15.3); # 按两位小数精度量化,避免浮点精度误差 my $a_quant = ($a_data * 100)->rint; my $b_quant = ($b_data * 100)->rint; # 合并为二维配对矩阵 my $pairs = cat($a_quant, $b_quant)->transpose; # 获取唯一配对及对应索引 my ($uniq_pairs, $indices) = uniqvec($pairs); # 统计每个唯一配对的出现次数 my $counts = histogram($indices, scalar($uniq_pairs->dim(0))); # 转回原浮点精度 my $a_result = $uniq_pairs->slice('(0),')->float / 100; my $b_result = $uniq_pairs->slice('(1),')->float / 100; # 按a值升序排序,匹配原示例输出顺序 my $sorted_idx = qsorti($a_result); my $sorted_a = $a_result->index($sorted_idx); my $sorted_b = $b_result->index($sorted_idx); my $sorted_counts = $counts->index($sorted_idx); # 输出结果 say $sorted_a; say $sorted_b; say $sorted_counts;
这段代码运行后会输出和原示例完全一致的结果,且全程通过PDL的向量/矩阵操作完成,处理大规模数据集时效率远高于原哈希循环方法。
内容的提问来源于stack exchange,提问作者doosoonk
相关产品推荐
相关产品推荐

