Prolog - 如何将 CSV 文件输出行转换为可查询术语?

问题描述 投票:0回答:1

我正在尝试学习使用 Prolog,并且非常惊喜地发现 SWI Prolog 提供了一个开箱即用的 CSV 库:https://www.swi-prolog.org/pldoc/man?section=csv

但是我不知道如何使用它,特别是使用以下数据(保存在

Data.csv
文件中):

Contract Name,Last Trade Date,Strike,Last Price,Bid,Ask,Volume,Open Interest,Implied Volatility
NVDA240315C00005000,2024-03-07 4:38PM EDT,5,917.6,857.55,861.1,85,"1,488",5375.00%
NVDA240315C00010000,2024-03-07 3:54PM EDT,10,914.1,852.65,854.95,5,35,2682.03%
NVDA240315C00015000,2024-03-06 12:26PM EDT,15,869.17,847.8,850,10,79,2273.05%
NVDA240315C00020000,2024-03-07 12:08PM EDT,20,897.83,842.3,844.8,2,83,1985.16%
NVDA240315C00025000,2024-03-07 4:05PM EDT,25,895.95,838,840.4,1,159,1885.35%
NVDA240315C00030000,2024-01-25 3:30PM EDT,30,582.67,757.25,759.8,2,35,0.00%
NVDA240315C00035000,2024-02-29 4:55PM EDT,35,763.1,827.3,829.8,1,40,1596.29%
NVDA240315C00040000,2024-02-14 12:29PM EDT,40,685.62,822.3,824.65,2,2,1507.62%
NVDA240315C00045000,2024-02-02 3:00PM EDT,45,616.74,776.35,779.1,1,1,0.00%
NVDA240315C00050000,2024-03-07 3:26PM EDT,50,874.25,812.4,814.85,2,2,1386.52%
NVDA240315C00060000,2024-02-07 2:36PM EDT,60,635.85,812.5,823.55,10,19,1887.65%
NVDA240315C00065000,2024-03-08 1:59PM EDT,65,809.33,797.3,799.6,75,57,1229.20%
NVDA240315C00070000,2024-03-08 1:59PM EDT,70,805,792.95,795.3,4,4,1226.07%
NVDA240315C00075000,2024-02-07 10:53AM EDT,75,614.79,797.55,803.15,-,1,1599.22%
NVDA240315C00080000,2024-02-14 12:29PM EDT,80,645.84,782.35,785,2,3,1131.25%
NVDA240315C00085000,2024-02-20 3:27PM EDT,85,599.85,778,780.3,1,3,1122.27%
NVDA240315C00090000,2024-02-26 2:06PM EDT,90,710.65,772.75,775,1,2,1079.59%

下面的片段:

:- use_module(library(csv)).

get_data(Rows) :-
    csv_read_file("Data.csv", Rows).

我可以通过 swipl 轻松获得以下内容:

> swipl .\Code.pl
1 ?- get_data(Rows).
Rows = [row('Contract Name', 'Last Trade Date', 'Strike', 'Last Price', 'Bid', 'Ask', 'Volume', 'Open Interest', 'Implied Volatility'), row('NVDA240315C00005000', '2024-03-07 4:38PM EDT', 5, 917.6, 857.55, 861.1, 85, '1,488', '5375.00%'), row('NVDA240315C00010000', '2024-03-07 3:54PM EDT', 10, 914.1, 852.65, 854.95, 5, 35, '2682.03%'), row('NVDA240315C00015000', '2024-03-06 12:26PM EDT', 15, 869.17, 847.8, 850, 10, 79, '2273.05%'), row('NVDA240315C00020000', '2024-03-07 12:08PM EDT', 20, 897.83, 842.3, 844.8, 2, 83, '1985.16%'), row('NVDA240315C00025000', '2024-03-07 4:05PM EDT', 25, 895.95, 838, 840.4, 1, 159, '1885.35%'), row('NVDA240315C00030000', '2024-01-25 3:30PM EDT', 
30, 582.67, 757.25, 759.8, 2, 35, '0.00%'), row('NVDA240315C00035000', '2024-02-29 4:55PM EDT', 35, 763.1, 827.3, 829.8, 1, 40, '1596.29%'), row(..., ..., ..., ..., ..., ..., ..., ..., ...)|...].

但是,返回结果看起来像是一个术语列表,并且存在两个问题:

  1. 如何跳过第一个标题行?我尝试查看文档,但找不到简单的方法。 ChatGPT 说我可能需要使用
    csv_read_stream
    来代替?你能举个例子吗?
  2. 我该怎么办
    Rows
    ?我想做的是在 swipl 中交互地进行查询,就像作为
    .pl
    文件加载的原始序言术语/谓词一样。例如。我希望发出这样的查询(语法可能有误,请纠正我):
    ?- row(Name, _, _, LastPrice, _, _, _, _, _), LastPrice > 650.
    查找LastPrice高于某个值的所有合约。

谢谢!

备注:

  • 导入csv文件数据以填充Prolog知识库部分回答了我的问题,但它说“在文档中查看”,我尝试过但无法理解 - 我需要关于如何忽略第一个标题行以及如何的具体代码示例使用返回的列表作为可查询的知识。
csv prolog swi-prolog
1个回答
0
投票

要获取列表的尾部部分,您可以在查询本身中进行模式匹配。

get_data([Header|Rows]).

现在有了您拥有的

Rows
,您需要检查列表中的
member

?- member(X, [1, 2, 3, 4]), X >= 3.
X = 3 ;
X = 4.

完整的查询将类似于:

get_data([Header|Rows]), member(row(Name, _, _, LP, _, _, _, _, _), Rows), LP > 650.
© www.soinside.com 2019 - 2024. All rights reserved.