我有一个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
中执行此操作,因为文件太大而无法容纳在内存中。
有什么建议吗?
答案 0 :(得分: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
字段分别为三位数,四位数和0
或1
。如果情况并非如此,那么您需要调整以m/
开头的行。
答案 1 :(得分: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)
。