0

我有一个csv客户数据文件,我想根据过去的行为找出他们购买产品的概率。

该表如下所示:

custId         prodId       purchased
   001           0001          0
   002           0001          0
   006           1001          1
   001           0501          0
   012           8001          0
   189           0071          0
   487           0001          1
   ...           ...          ...

custId是客户 ID,prodId是产品,列既不是唯一的,也不是custId-prodId唯一的,因为客户可以多次显示相同的产品。

理想的输出是这样的:

 custId         purchased
   001           .0999
   002           0
   006           1
   012           0
   189           .75
   487           1
   ...          ...   

我正在考虑这样做,bash因为文件太大而无法放入内存。

有什么建议么?

4

2 回答 2

1

由于 Jonah Bishop 和 choroba 都在上面评论说你应该使用 Perl,我倾向于同意,这是一个使用 Perl 来执行此操作的 Bash 命令:

perl -e \
  ' use warnings;
    use strict;
    my %custCounts;
    my %custSums;
    while(<>)
    {
      m/^(\d{3}),\d{4},([01])$/
        or die "ruakh doesn'"'"'t understand your CSV file format";
      ++$custCounts{$1};
      ++$custSums{$1} if $2;
    }
    foreach my $custId (sort keys %custCounts)
    {
      print "$custId,", ($custSums{$custId}||0) / $custCounts{$custId}, "\n";
    }
  ' < customerData.csv

以上假设您的 CSV 文件如下所示:

001,0001,0
002,0001,0
006,1001,1
001,0501,0
012,8001,0
189,0071,0
487,0001,1

字段分别为三位数、四位数和01。如果不是这种情况,那么您需要调整以m/.

于 2012-09-20T18:24:59.723 回答
1

这是一个使用的快速示例awk

awk '{++shown[$1]; if ($3 > 0) ++purchased[$1];}END{for (cust in purchased) print cust, purchased[cust]/shown[cust]}' datafile

没有错误检查,所以如果你的输入有偏差,它就会死掉;此外,您必须进行预处理以删除任何标题等。如果您的字段分隔符不是空格,请使用 'awk -F, ...' 将字段分隔符设置为 ',' 或其他。

此外,这仅打印具有非零百分比的条目,以包括所有客户,更改for (cust in purchased)for (cust in shown).

于 2012-09-20T18:25:19.423 回答