4.2.1 加载和解析数据

本文介绍如何使用F#语言解析CSV文件数据,并通过递归函数将数据转换为适合图表绘制应用的数据结构。

4.2.1 加载和解析数据

 

作为第一步,我们将实现一个函数 convertDataRow,从 CSV 文件中取一行作为字符串,把这一行拆成两部分,以元组形式返回。函数实现后,就可以立即进行测试,输入一个样本(字符串"Test reading,1234”),应该能够正确解析。清单 4.2 是函数的代码和测试结果。

 

清单 4.2 解析 CSV 文件的一行 (F# Interactive)

> open System;;

> let convertDataRow(csvLine:string) =  [1]

let cells = List.ofseq(csvLine.Split(','))    [2]

match cells with

| title::number::_ –>    <-- 可能有两个或更多单元

let parsedNumber = Int32.Parse(number)

(title, parsedNumber)

| _ -> failwith "Incorrect dataformat!"  <-- 报告错误

;;

val convertDataRow : string -> string *int

 

> convertDataRow("Testingreading,1234");;  [3]

val it : string * int = ("Testingreading", 1234)

 

启动 F# Interactive 以后,我们需要从 System 命名空间导入功能;只有打开这个命名空间,才能在代码中要使用 Int32.Parse 方法。这必须显式导入,但是,F# 核心库的函数,比如,List.ofseq,默认就是可用的。

函数 convertDataRow [1]取一个字符串作为参数,以逗号作为分隔符,把值拆分成列表,我们用.NET 中标准的 Split 方法执行此操作。当调用值的实例方法时,F# 编译器需要提前知道值的类型。不幸的是,在这里,类型推断没有任何其他方式来推断出类型,因此,我们要使用类型批注,显式声明 csvLine 的类型是字符串[2]。

Split 方法的声明使用 C#  的params 关键字,参数为数量可变的字符,我们只指定一个分隔符:逗号。这个方法的结果是一个字符串数组,但我们想要使用的是列表,所以,要将结果转换为列表,我们使用 F # List 模块的 ofseq 函数。我们将在第十和第十二章讨论有关数组和其他集合类型。

有了列表以后,我们就可以使用 match 结构,检查格式是否正确。如果包含两个或更多的值,将匹配第一种情况(title::number:: _),标题指定给 title、数值指定给 number,其余列(如果有)被忽略。在这个分支中,我们使用 Int32.Parse 把字符串转换为整数,返回的元组包含标题和这个值;第二个分支触发标准的 .NET 异常。

如果看到这个函数的签名,就能明白,取字符串参数,返回一个元组,第一个值是字符串,第二个值是整数。这是完全符合我们的预期:标题返回作为字符串,第二列的数值转换为整数。下一行演示了在 F# Interactive 中测试函数是如何的方便[3]。示例调用的结果是元组,包含“Testing reading” 作为标题,"1234"作为数值。

 

F# 处理 .NET 字符串

 

在 F# 中处理 .NET 字符串,一般会使用通常的 .NET 方法。我们现在就来看看如何在 F# 中使用,先选几个 String 类中的静态方法,这些方法就好像是普通的 F# 函数(使用 String 类名)。这些函数的参数值必须在括号内指定,就像是以逗号分隔的元组。在类型签名中,元组写成星号:

 

■ String.Concat (重载):接受可变数量的字符串或对象类型的参数值,并返回一个把所有的这些都连接起来的字符串:

 

> String.Concat("1 + 3", 3);;

val it : string = "1 + 33"

 

■ String.Join (sep:string * strs:string[]) : string:把字符串数组,即参数strs,使用指定的分隔符,即 sep 参数连接起来,可以使用 [| ... |] 语法来构建数组:

 

> String.Join(", ", [|"1"; "2"; "3" |]);;

val it : string = "1, 2, 3"

 

在.NET 中,字符串也是对象,也有实例成员,在 F# 中使用典型的点表示法。这一点,在前面的示例中,我们已经看到过,当拆分字符串时,使用了 str.Split。下面的示例假定我们有一个字符串 str 包含"Hello World!":

■ str.Length:返回字符串长度的属性,在 F# 中,访问属性的方法与 C# 相同,所以读这个属性不需要括号:

 

> str.Length;;

val it : int = 12

 

■ str.[index:int]:指定字符串的索引,写在方括号内,返回由 index 指定位置的字符。注意,在方括号的前面仍需要点,与 C# 中不同:

 

> str.[str.Length - 1];;

val it : char = '!'

 

我们还可以使用 FSharp.PowerPack.dll 库中的函数;F# 中大多数字符串处理代码可以使用 .NET 方法来实现。

 

在前面的清单中,我们实现了 convertDataRow 函数,取 CSV 文件中的一行字符串作为参数,返回元组,包含标签和数值。下一步,我们将实现一个函数,参数为字符串列表,使用 convertDataRow,将每个字符串转换为元组,清单 4.3 就是这个函数;然后,立即进行测试,解析一个字符串列表样本。

 

清单 4.3 解析输入文件的多行 (F# Interactive)

> let rec processLines(lines) =

   matchlines with

   | [] -> []    [1]

   |currentLine::remaining ->    [2]

     letparsedLine = convertDataRow(currentLine)  <-- 处理列表头

     letparsedRest = processLines(remaining) <-- 递归处理列表尾

     parsedLine :: parsedRest

;;

val processLines : string list ->(string * int) list

 

> let testData = processLines["Test1,123"; "Test2,456"];;  [3]

val testData : (string * int) list =[("Test1", 123); ("Test2", 456)]

 

这个函数在许多方面与我们在前一章实现的列表处理函数相似。可以看到,声明这个函数使用了 let rec 关键字,因此,它是递归的。它的参数(lines)为字符串列表,使用模式匹配,检查列表是空列表,还是cons cell。对于空列表,直接返回元组的空列表[1];如果模式匹配执行的分支是针对 cons cell 的[2],会把列表中的第一个元素的值指定给 currentLine,列表的其余元素指定给 remainning。此分支的代码首先处理一行,使用清单 4.2 的 convertDataRow 函数,然后,以递归方式处理列表中的其余部分。最后,代码构造一个新的cons cell,包含:处理过的行作为列表头,递归处理的列表其余部分作为列表尾。这样,函数对列表中的每个字符串,执行 convertDataRow,把结果收集成新的列表。

为更好地理解 processLines 函数做了什么,我们还可以通过 F# Interactive,查看输出的类型签名,函数的参数为字符串列表(string list 类型),返回为包含类型为元组(strings * int)的列表。这正是解析一行的函数所返回的类型,因此,函数做的很正确。我们通过调用样本列表作为参数值[3],进行验证。可以看到,由 F# Interactive 输出的结果:是包含两个元组的列表,元组有一个字符串和一个数字,所以,函数运行良好。

现在,我们有了一个函数,将字符串列表转换为将在图表绘制应用程序中使用的数据结构。我们在实现关键的数据处理部分之前,还需要看一个简单的工具程序。

 

【轴承故障诊断】加权多尺度字典学习模型(WMSDL)及其在轴承故障诊断上的应用(Matlab代码实现)内容概要:本文介绍了加权多尺度字典学习模型(WMSDL)在轴承故障诊断中的应用,并提供了基于Matlab的代码实现。该模型结合多尺度分析与字典学习技术,能够有效提取轴承振动信号中的故障特征,提升故障识别精度。文档重点阐述了WMSDL模型的理论基础、算法流程及其在实际故障诊断中的实施步骤,展示了其相较于传统方法在特征表达能力诊断准确性方面的优势。同时,文中还提及该资源属于一个涵盖多个科研方向的技术合集,包括智能优化算法、机器学习、信号处理、电力系统等多个领域的Matlab仿真案例。; 适合人群:具备一定信号处理机器学习基础,从事机械故障诊断、工业自动化、智能制造等相关领域的研究生、科研人员及工程技术人员。; 使用场景及目标:①学习并掌握加权多尺度字典学习模型的基本原理与实现方法;②将其应用于旋转机械的轴承故障特征提取与智能诊断;③结合实际工程数据复现算法,提升故障诊断系统的准确性鲁棒性。; 阅读建议:建议读者结合提供的Matlab代码进行实践操作,重点关注字典学习的训练过程与多尺度分解的实现细节,同时可参考文中提到的其他相关技术(如VMD、CNN、BILSTM等)进行对比实验与算法优化。
【硕士论文复现】可再生能源发电与电动汽车的协同调度策略研究(Matlab代码实现)内容概要:本文档围绕“可再生能源发电与电动汽车的协同调度策略研究”展开,旨在通过Matlab代码复现硕士论文中的核心模型与算法,探讨可再生能源(如风电、光伏)与大规模电动汽车接入电网后的协同优化调度方法。研究重点包括考虑需求侧响应的多时间尺度调度、电动汽车集群有序充电优化、源荷不确定性建模及鲁棒优化方法的应用。文中提供了完整的Matlab实现代码与仿真模型,涵盖从场景生成、数学建模到求解算法(如NSGA-III、粒子群优化、ADMM等)的全过程,帮助读者深入理解微电网与智能电网中的能量管理机制。; 适合人群:具备一定电力系统基础知识Matlab编程能力的研究生、科研人员及从事新能源、智能电网、电动汽车等领域技术研发的工程人员。; 使用场景及目标:①用于复现验证硕士论文中的协同调度模型;②支撑科研工作中关于可再生能源消纳、电动汽车V2G调度、需求响应机制等课题的算法开发与仿真验证;③作为教学案例辅助讲授能源互联网中的优化调度理论与实践。; 阅读建议:建议结合文档提供的网盘资源下载完整代码,按照目录顺序逐步学习各模块实现,重点关注模型构建逻辑与优化算法的Matlab实现细节,并通过修改参数进行仿真实验以加深理解。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值