我有4个不同来源的多个数据列表,其中有一组共同的ID,我希望根据ID合并在一起,基本上以新列表结束,每个ID一个,每个源一个条目.
来自4个源中的每个源的输出列表中的对象看起来像这样:
type data = {ID : int; value : decimal;}
Run Code Online (Sandbox Code Playgroud)
所以,例如我会:
let sourceA = [data1, data2, data3];
let sourceB = [data1, data2, data3];
let sourceC = [data1, data2, data3];
let sourceD = [data1, data2, data3];
Run Code Online (Sandbox Code Playgroud)
(我意识到这段代码无效,只是试图给出一个基本的想法......列表实际上是从数据库中提取和生成的)
然后我想获取sourceA,sourceB,sourceC和sourceD并将它们处理成包含如下对象的列表:
type dataByID = {ID : int; valueA : decimal; valueB : decimal; valueC : decimal; valueD : decimal; }
Run Code Online (Sandbox Code Playgroud)
...然后我可以用CSV打印出来,其中第一列是ID,而coulmns 2-5是源A-D的数据,对应于该行中的ID.
我对F#完全不熟悉,那么处理这些数据的最佳方法是什么,以便我通过ID匹配所有源数据值?
我正在学习F#和FSharp.Data库.我有一个任务,我需要阅读20个CSV文件.每个文件具有不同的列数,但记录具有相同的性质:键入日期字符串,其余所有列都是浮点数.在将结果保存到数据库之前,我需要对float格式数据列进行一些统计计算.虽然我得到了所有的管道逻辑工作:
解决方案远非可接受.我以为我可以创建一个通用的顶级函数作为循环遍历所有文件的驱动程序.然而,经过几天的尝试,我无处可去.
FSharp.Data CSV类型提供程序具有以下模式:
type Stocks = CsvProvider<"../docs/MSFT.csv">
let msft = Stocks.Load("http://ichart.finance.yahoo.com/table.csv?s=MSFT")
msft.Data |> Seq.map(fun row -> do something with row)
...
Run Code Online (Sandbox Code Playgroud)
我试过了:
let mainfunc (typefile:string) (datafile:string) =
let msft = CsvProvider<typefile>.Load(datafile)
....
Run Code Online (Sandbox Code Playgroud)
这不起作用,因为CsvProvider抱怨typefile不是有效的常量表达式.我猜测类型提供者必须要求文件在编码时推断出列的类型,在使用相关信息调用mainfunc的代码之前,不能推迟类型推断.
然后我尝试将Type作为参数传递给mainfunc
也不
let mainfunc (typeProvider:CsvProvider<"../docs/MSFT.csv">) =
....
Run Code Online (Sandbox Code Playgroud)
也不
let mainfunc<typeProvider:CsvProvider<"../docs/MSFT.csv">> =
....
Run Code Online (Sandbox Code Playgroud)
工作.
然后我试图通过MSFT
type Stocks = CsvProvider<"../docs/MSFT.csv">
let msft = Stocks.Load("http://ichart.finance.yahoo.com/table.csv?s=MSFT")
Run Code Online (Sandbox Code Playgroud)
进入mainFunc.根据intellisence,MSFT有一种类型CsvProvider<...>和MSFT.Data类型seq<CsvProvider<...>>.我试图用这两个显式类型声明一个输入参数,但它们都不能通过编译.
有谁可以请帮助并指出我正确的方向?我在这里错过了一些基本的东西吗?任何.net类型和类对象都可以在F#函数中用于显式指定参数类型,但是我可以对类型提供程序中的类型执行相同的操作吗?
如果上述问题的答案是否定的,那么使逻辑通用处理20个文件甚至200个不同文件的替代方法是什么?
我有一个NUnit单元测试,它是用普通的F#库编写的,但它是针对可移植类库中的F#代码.
当我运行此测试(在Visual Studio 2013中)时,我得到以下异常:
Result Message: System.MissingMethodException : Method not found:
'Microsoft.FSharp.Control.FSharpAsync`1<System.IO.TextReader> FSharp.Data.Runtime.IO.asyncReadTextAtRuntime(System.Boolean, System.String, System.String, System.String, System.String)'.
Run Code Online (Sandbox Code Playgroud)
这就是我在Portable Class Library中的app.config中所拥有的:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="FSharp.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.3.1.0" newVersion="3.3.1.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
Run Code Online (Sandbox Code Playgroud)
这就是我在普通F#库的app.config中所拥有的:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="FSharp.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.3.1.0" newVersion="4.3.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="nunit.framework" publicKeyToken="96d09a1eb7f44a77" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.6.3.13283" newVersion="2.6.3.13283" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
Run Code Online (Sandbox Code Playgroud) 我有一个我在VS2013中构建的F#程序.我打算在安装了.NET Framework 4.5的Windows 2008 R2服务器上部署它.现在,当我在visual studio中构建程序时,它会在debug/bin目录(MyProgram.exe)中创建一个exe.我是否需要在exe中包含fharp.core.dll的副本?或者,构建过程是否会自动编译必要的依赖DLL(fsharp.core,fsharp.data,fsharp.data.TypeProviders)?我在网上搜索的大部分研究似乎都是关注VS2010而我目前还没有使用fsc,exe.
感谢您提供的任何见解.
我怎样才能在f sharp中创建一个csv文件并在其中写入以下记录类型?
type test = { G:array<double>; P:array<double>; GG:array<double>; PP:array<double> }
let table = [for x in 0..(Un0.Length - 1) ->
let b = Un0.[x] in
if b=0.0 then {G=0.0; P=0.0; GG=0.0; PP=0.0}
else {G=G_0.[x]/b; P=P0.[x]/b; GG=G0.[x]/b; PP=PP0.[x]/b}]
Run Code Online (Sandbox Code Playgroud) 我FSharp.Data HTMLProvider用来提取表行:
let [<Literal>] URL = "../DailyResultsType.html"
type RawResults = HtmlProvider<URL>
let results = RawResults.Load(URL).Tables
let dailySeq =
results.Table2.Rows
|> Seq.tail
Run Code Online (Sandbox Code Playgroud)
循环遍历行(row是a seq<HtmlProvider<...>.Table2.Row>):
for row in dailySeq do
printfn "%A" row
Run Code Online (Sandbox Code Playgroud)
结果是:
(1, nan, nan, 2)
(1, nan, nan, 3)
~~~
Run Code Online (Sandbox Code Playgroud)
像#2和#3这样的列由提供者自动输入decimal,double因为HTML包含诸如"$ 12.00"或"$ 12"之类的字符串.
我可以动态改变这些列的类型内从返回的类型HtmlProvider<URL>在运行时(从双串即)(但我更喜欢数字类型,所以我可以Deedle结果)
或者将运行时字符串转换应用于这些列中的值以删除非数字字符,以便它们是有效的decimal/double/int类型...
或者我错过了一个基本概念(很可能是因为我是F#noobie)
我有一个包含6列和678,552行的csv文件.不幸的是,我不能共享任何数据样本,但类型是直截了当:int64,int64,date,date,string,string并且没有缺失值.
是时候在R中的数据帧中加载这些数据read.table:~3秒.
是时候在F#中使用CsvFile.Load加载这些数据:~3秒.
是时候在F#中的Deedle数据帧中加载这些数据:~7秒.
向inferTypes=falseDeedle 添加并提供架构Frame.ReadCsv可将时间缩短至约3秒
是时候在F#中使用CsvProvider加载这些数据:~5分钟.
在我定义Schema参数中的类型后,这5分钟甚至可以消除F#用来推断它们的时间.
我知道类型提供程序需要做的不仅仅是R或CsvFile.Load,以便将数据解析为正确的数据类型,但我对x100速度惩罚感到惊讶.更令人困惑的是Deedle加载数据所需的时间,因为它还需要推断类型和适当的转换,组合系列等.我实际上预计Deedle需要比CsvProvider更长的时间.
在这个问题中,CsvProvider的不良性能是由大量的列引起的,这不是我的情况.
我想知道我是做错了什么,或者是否有任何方法可以加快速度.
只是为了澄清:创建提供者几乎是即时的.当我迫使生成的序列被实现时,Seq.length df.Rowsfsharpi提示返回需要大约5分钟.
我在Linux系统上,单声道v4.6.1上的F#v4.1.
这是CsvProvider的代码
let [<Literal>] SEP = "|"
let [<Literal>] CULTURE = "sv-SE"
let [<Literal>] DATAFILE = dataroot + "all_diagnoses.csv"
type DiagnosesProvider = CsvProvider<DATAFILE, Separators=SEP, Culture=CULTURE>
let diagnoses = DiagnosesProvider()
Run Code Online (Sandbox Code Playgroud)
EDIT1: 我添加了Deedle将数据加载到帧中的时间.
EDIT2:
添加了Deedle所采用的时间inferTypes=false和提供的模式.
此外,CacheRows=false按照注释中的建议在CsvProvider中提供对加载时间没有明显影响.
EDIT3:
好的,我们到了某个地方.由于一些特殊的原因,它似乎Culture …
尝试将 SQLTypeProvider 与 postgres 一起使用时,运行时出现以下错误
dotnet build
Run Code Online (Sandbox Code Playgroud)
错误 FS3033:类型提供程序 'FSharp.Data.Sql.SqlTypeProvider' 报告错误:无法加载文件或程序集 'System.Runtime.CompilerServices.Unsafe, Version=4.0.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'。该系统找不到指定的文件。[/home/sashan/code/titan/src/Server/Server.fsproj]
我的数据提供者是这样的:
type SQL = SqlDataProvider<
ConnectionString = pg_dev_conn_string,
DatabaseVendor = Common.DatabaseProviderTypes.POSTGRESQL,
UseOptionTypes = true >
Run Code Online (Sandbox Code Playgroud)
如果我将其更改为以下内容
type SQL = SqlDataProvider<
ConnectionString = pg_dev_conn_string,
DatabaseVendor = Common.DatabaseProviderTypes.POSTGRESQL,
ResolutionPath = "/home/sashan/code/dotnet/2.1.500/sdk/NuGetFallbackFolder/system.runtime.compilerservices.unsafe/4.5.1/lib/netcoreapp2.0",
UseOptionTypes = true >
Run Code Online (Sandbox Code Playgroud)
错误消失了,但我不明白为什么。修复看起来真的很奇怪。为什么我必须将它指向我的项目之外的文件?System.Runtime.CompilerServices.Unsafe.dll 不应该位于编译器可以找到它的项目子目录之一中的某个位置吗?
我是F#的初学者,我正在尝试使用CsvProvider并重现这里给出的例子
http://fsharp.github.io/FSharp.Data/library/CsvProvider.html
所以在F#互动中,我打字
>type Stocks = CsvProvider<"MSFT.csv">;;
type Stocks = CsvProvider<...>
> let msft = CsvProvider<"MSFT.csv">.GetSample();;
val msft : CsvProvider<...>
> msft;;
val it : CsvProvider<...> =
FSharp.Data.Runtime.CsvFile`1[System.Tuple`1[System.String]]
{Headers = Some [|"MSFT.csv"|];
NumberOfColumns = 1;
Quote = '"';
Rows = seq [];
Separators = ",";}
> let firstRow = msft.Rows |> Seq.head;;
System.ArgumentException: The input sequence was empty.
Parameter name: source
> at Microsoft.FSharp.Collections.SeqModule.Head[T](IEnumerable`1 source)
at <StartupCode$FSI_0044>.$FSI_0044.main@()
Stopped due to error
Run Code Online (Sandbox Code Playgroud)
我的理解是CsvProvider基于CSV文件创建一个类型,该文件使得以后能够以相同的格式读取该文件或不同的文件/流.我认为我没有目录问题,因为如果文件位于错误的目录中,该函数将返回错误.当创建msft时,F#表示NumberOfColumns = 1,但这显然是错误的.
这也不起作用
> let msft = Stocks.Parse("MSFT.csv");; …Run Code Online (Sandbox Code Playgroud) 为什么如果我使用CsvProvider<>F#创建一个新的CSV类型,如下所示:
type ThisCsv = CsvProvider<Schema = "A (decimal), B (string), C (decimal)", HasHeaders = false>
Run Code Online (Sandbox Code Playgroud)
然后创建/填充/保存.csv,生成的文件不包含我指定的架构中的标头?似乎应该有一种方法在最终的.csv文件中包含标题,但事实并非如此.
设置HasHeaders = true错误,因为没有提供样本.工作的唯一方法HasHeaders = true是获得样本.csv.在我看来,应该有一种方法来指定没有样本的模式,并在最终文件中包含标头.
我在使用时遗漏[nameOfMyCSV].Save()了哪些内容可以包含模式中的标题,或者这可以不做?