Csv 使用Prolog解析数值数据?

Csv 使用Prolog解析数值数据?,csv,prolog,logic,swi-prolog,dcg,Csv,Prolog,Logic,Swi Prolog,Dcg,我是prolog新手,正在考虑将其用于一个小型数据分析应用程序。以下是我想要实现的目标: 我有一个CSV文件,其中包含以下数据: a,b,c d,e,f g,h,i ... 数据纯粹是数字,我需要做以下工作:1,我需要根据以下方案对行进行分组: 那么上面是怎么回事 我从第一行开始,第一列中的值为“a”。然后,我继续沿着行往下走,直到我碰到一行,它在第一列中的值与'a'相差一定的量'z'。然后重复该过程,在该过程完成后形成许多“组” 对于这些组中的每一组,我想找出第二列和第三列的平均值(例如,

我是prolog新手,正在考虑将其用于一个小型数据分析应用程序。以下是我想要实现的目标:

我有一个CSV文件,其中包含以下数据:

a,b,c
d,e,f
g,h,i
...
数据纯粹是数字,我需要做以下工作:1,我需要根据以下方案对行进行分组:

那么上面是怎么回事

我从第一行开始,第一列中的值为“a”。然后,我继续沿着行往下走,直到我碰到一行,它在第一列中的值与'a'相差一定的量'z'。然后重复该过程,在该过程完成后形成许多“组”

对于这些组中的每一组,我想找出第二列和第三列的平均值(例如,对于上图中的第一组,第二列的平均值为:(b+e+h)/3)

我确信这可以在prolog中完成。然而,我有50000多行数据,而且由于prolog是声明性的,我不确定prolog在完成上述任务方面的效率如何


编制一个prolog程序来完成上述任务是否可行,这样程序的效率就不会明显低于程序模拟吗?

这段代码可能是您任务的起点

:- [library(dcg/basics)].

rownum(Z, AveList) :- phrase_from_file(row_scan(Z, [], [], AveList), 'numbers.txt').

row_scan(Z, Group, AveSoFar, AveList) -->
    number(A),",",number(B),",",number(C),"\n",
    { row_match(Z, A,B,C, Group,AveSoFar, Group1,AveUpdated) },
    row_scan(Z, Group1, AveUpdated, AveList).
row_scan(_Z, _Group, AveList, AveList) --> "\n";[].

% row_match(Z, A,B,C, Group,Ave, Group1,Ave1) 
row_match(_, A,B,C, [],Ave, [(A,B,C)],Ave).
row_match(Z, A,B,C, [H|T],Ave, Group1,Ave1) :-
    H = (F,_,_),
    (  A - F =:= Z
    -> aggregate_all(agg(count,sum(C2),sum(C3)),
        member((_,C2,C3), [(A,B,C), H|T]), agg(Count,T2,T3)),
       A2 is T2/Count, A3 is T3/Count,
       Group1 = [], Ave1 = [(A2,A3)|Ave]
    ;  Group1 = [H,(A,B,C)|T], Ave1 = Ave
    ).
有了这个输入

1,2,3
4,5,6
7,8,9
10,2,3
40,5,6
70,8,9
16,0,0
屈服

?- rownum(6,L).
L = [ (3.75, 4.5), (5, 6)] 

此代码段可以作为任务的起点

:- [library(dcg/basics)].

rownum(Z, AveList) :- phrase_from_file(row_scan(Z, [], [], AveList), 'numbers.txt').

row_scan(Z, Group, AveSoFar, AveList) -->
    number(A),",",number(B),",",number(C),"\n",
    { row_match(Z, A,B,C, Group,AveSoFar, Group1,AveUpdated) },
    row_scan(Z, Group1, AveUpdated, AveList).
row_scan(_Z, _Group, AveList, AveList) --> "\n";[].

% row_match(Z, A,B,C, Group,Ave, Group1,Ave1) 
row_match(_, A,B,C, [],Ave, [(A,B,C)],Ave).
row_match(Z, A,B,C, [H|T],Ave, Group1,Ave1) :-
    H = (F,_,_),
    (  A - F =:= Z
    -> aggregate_all(agg(count,sum(C2),sum(C3)),
        member((_,C2,C3), [(A,B,C), H|T]), agg(Count,T2,T3)),
       A2 is T2/Count, A3 is T3/Count,
       Group1 = [], Ave1 = [(A2,A3)|Ave]
    ;  Group1 = [H,(A,B,C)|T], Ave1 = Ave
    ).
有了这个输入

1,2,3
4,5,6
7,8,9
10,2,3
40,5,6
70,8,9
16,0,0
屈服

?- rownum(6,L).
L = [ (3.75, 4.5), (5, 6)] 

参见OP报告,他花了5-15秒处理了5-10MB的数据。我对这种效率水平没有意见(50000多行只占用了大约6MB)。但是,时间是否会随着文件大小线性扩展?或者更确切地说,是否可以在prolog中设计代码,使时间与文件大小成线性比例(应该是这样的,因为我只需要遍历所有行一次就可以完成我正在寻找的内容)。您对缩放的关注是创建
库(pio)
的动机。代码现在可以无副作用运行,并且空间开销仅与开放选择点的数量成比例。通常,对于确定性解析,这意味着恒定的空间开销。这在恒定的空间中运行,因此
grep
与过程解析一样节省空间。参见OP报告,他花了5-15秒处理了5-10MB的数据。我对这种效率水平没有意见(50000多行只占用了大约6MB)。但是,时间是否会随着文件大小线性扩展?或者更确切地说,是否可以在prolog中设计代码,使时间与文件大小成线性比例(应该是这样的,因为我只需要遍历所有行一次就可以完成我正在寻找的内容)。您对缩放的关注是创建
库(pio)
的动机。代码现在可以无副作用运行,并且空间开销仅与开放选择点的数量成比例。通常,对于确定性解析,这意味着恒定的空间开销。这在恒定空间中运行,因此
grep
与过程性解析一样节省空间。