映射到Deedle框架 [英] Map to Deedle Frame
问题描述
我试图将一个
Map< string,seq< DateTime * float>>
转换为Deedle数据框( http://bluemountaincapital.github.io/Deedle/tutorial.html#creating )。 我已经准备了以下代码:
let folderFnct(aFrame:Frame)colName datesAndValues =
let newSerie = Series(Seq.map(fun x - > fst x)datesAndValues,Seq.map(fun y - > snd y)datesAndValues)
let newFrame = aFrame.Join([colName] ,[newSerie],kind = JoinKind.Inner)
newFrame
let mapToDeedleFrame myMap frame =
Map.fold(fun s ticker datesAndValues - > folderFnct s框架dateAndValues)框架myMap
mapToDeedleFrame
折叠使用现有框架映射。文件夹功能 folderFnct
:
- 采取框架
- 在框架中使用Map键作为列名,
- 处理值(
< DateTime * float>
)
问题出在:
let newFrame = aFrame.Join([colName],[newSerie],kind = JoinKind.Inner)
其中:
字段,构造函数或成员Join未定义
我已经确定了三个潜在的问题原因:
- 为什么没有定义
aFrame.Join
?我尝试明确指定aFrame的类型aFrame
- 如何提供给
mapToDeedleFrame
空框架 - 我应该在
folderFnct
中匹配,而aFrame
是空的?
非常感谢!
编辑1
根据Tomas的建议,这是我迄今为止所发现的。
let folderFnct(aFrame:Frame<'a,'b>)columnName(seqOfTuples:seq<'a *'b>)=
让newSerie = Series(Seq.map(fun x - > fst x)seqOfTuples,Seq.map(fun y - > snd y)seqOfTuples)
let otherFrame = Frame([columnName],[newSerie])
let newFrame = aFrame.Join((otherFrame),kind = JoinKind.Inner)
newFrame
let mapToDeedleFrame myMap frame =
Map.fold (fun state k vals - > folderFnct state k vals)frame myMap
<缺少的最后一步是:如何快速传递一个空的框架(可能避免创建一个虚拟框架)到 mapToDeedleFrame
?我试过 []
如
let frame = mapToDeedleFrame mapTS [ ]
这可能是一个愚蠢的问题,但我是F#的新手,我想知道是否有一个空的
类型。
关注问题
在源文件中,我阅读( https://github.com/BlueMountainCapital/Deedle/blob/master/src /Deedle/Frame.fs ):
member frame.Join<'V>(colKey,series:Series< ;'TRowKey,'V>,kind,lookup)=
let otherFrame = Frame([colKey],[series])
frame.Join(otherFrame,kind,lookup)
而在功能描述中弹出屏幕:
< img src =https://i.stack.imgur.com/EEPe4.jpgalt =Printscreen>
从上图可以看出, Frame的类型与colKey相同,而据我所知,colKey只是从系列中加入的数据帧列的关键。作为一个完整的noob,我很困惑..
编辑2
我重写了代码:
let seriesListMapper(colName:string,series:Series<'a,'b>)=
[colName =>系列] |>框架
let frameListReducer(accFrame:Frame<'a,'b>)(aFrame:Frame<'a,'b>)=
accFrame.Join(aFrame, kind = JoinKind.Outer)
let seriesListToFrame(seriesList:List< string * Series<'a,'b>)=
seriesList |> List.map(fun elem - > seriesListMapper elem)|> List.reduce(fun acc elem - > frameListReducer acc elem)
问题是: p>
let frame = seriesListToFrame seriesList
将帧返回为Frame,而seriesList代替(string * Series< DateTime,float>)列表
我认为问题是:
let seriesListMapper(colName:string,series:Series<'a, 'b>)=
[colName =>系列] |>框架
事实上, seriesListMapper
表示为
seriesListMapper:colName:string * series:系列<'a,'b> - >框架<'a,string>
我不明白为什么值转换为 string
从
float
。
一个有趣的事情是绘制框架与 frame.Format()
实际上确认数据看起来正确。
在这个奇怪的转换到 string
folderFnct
的类型注释,您有 aFrame:Frame
。然而,表示数据帧的类型是具有两个类型参数的通用类型(分别表示行和列的索引类型),因此注释应为 aFrame:Frame< _,_>
。
向系统添加框架的另一种方法是使用变异操作:
aFrame.AddSeries(colName,newSeries)
但是,支持左连接(数据帧只能通过添加新的系列来进行突变,但不能以改变索引的方式)。但是,您可能可以使用此方法,然后在构建框架后将所有缺失的值从框架中删除。
编辑:要回答关于通用类型的问题:
-
系列< K,V>
代表带有K
类型的键的系列,其中包含类型为V
的值(例如,通常索引观察的系列将具有K = int
和V = float
) -
code>框架< R,C> 表示包含异构数据(每列可能变化的类型)的帧,其中行被索引为$ code> R 列由
C
索引。通常,索引框架R = int
,通常,您的列将被命名为C = string
(但是您可以其他指标)
I am learning F#.
I am trying to convert a Map<string, seq<DateTime * float>>
to a Deedle dataframe (http://bluemountaincapital.github.io/Deedle/tutorial.html#creating).
I have prapared the following code:
let folderFnct (aFrame:Frame) colName datesAndValues =
let newSerie = Series(Seq.map (fun x -> fst x) datesAndValues, Seq.map (fun y -> snd y) datesAndValues)
let newFrame = aFrame.Join([colName], [newSerie], kind=JoinKind.Inner)
newFrame
let mapToDeedleFrame myMap frame =
Map.fold ( fun s ticker datesAndValues -> folderFnct s ticker datesAndValues) frame myMap
mapToDeedleFrame
folds the map using an existing frame. The folder function folderFnct
:
- takes the frame
- uses the Map key as column name in the frame, and
- processes the values (
<DateTime * float>
) making a Series of them.
The problem is with:
let newFrame = aFrame.Join([colName], [newSerie], kind=JoinKind.Inner)
where:
The field, constructor or member 'Join' is not defined
I have identified three potential causes of the issue:
- Why is
aFrame.Join
not defined? I tried explicitly specifying the type ofaFrame
- How can I feed to
mapToDeedleFrame
an empty frame? - Should I pattern match in
folderFnct
against the case whereaFrame
is empty?
Thanks a lot!
EDIT 1
Based on Tomas suggestion, this is what I have cranked out so far.
let folderFnct (aFrame:Frame<'a, 'b>) columnName (seqOfTuples: seq<'a*'b>) =
let newSerie = Series(Seq.map (fun x -> fst x) seqOfTuples, Seq.map (fun y -> snd y) seqOfTuples)
let otherFrame = Frame([columnName], [newSerie])
let newFrame = aFrame.Join((otherFrame), kind=JoinKind.Inner)
newFrame
let mapToDeedleFrame myMap frame =
Map.fold ( fun state k vals -> folderFnct state k vals) frame myMap
The last step missing is: how do I quickly pass an empty Frame (maybe avoiding creating a dummy one) to mapToDeedleFrame
? I have tried []
as in
let frame = mapToDeedleFrame mapTS []
This may be a silly question, but I am new to F# and I was wondering if there is an Empty
type built in the language.
FOLLOW UP QUESTION
In the source file I read (https://github.com/BlueMountainCapital/Deedle/blob/master/src/Deedle/Frame.fs):
member frame.Join<'V>(colKey, series:Series<'TRowKey, 'V>, kind, lookup) =
let otherFrame = Frame([colKey], [series])
frame.Join(otherFrame, kind, lookup)
while in the function description popping out on the screen:
From the picture above I would guess that the type of the Frame is the same as colKey, while, as I understood, colKey is just the key to the dataframe column added with the join from the serie. As a complete noob, I am quite confused..
EDIT 2
I have rewritten the code:
let seriesListMapper (colName:string, series:Series<'a, 'b>) =
[colName => series] |> frame
let frameListReducer (accFrame: Frame<'a, 'b>) (aFrame: Frame<'a, 'b>) =
accFrame.Join(aFrame, kind=JoinKind.Outer)
let seriesListToFrame (seriesList: List<string * Series<'a, 'b>>) =
seriesList |> List.map (fun elem -> seriesListMapper elem) |> List.reduce(fun acc elem -> frameListReducer acc elem)
The problem is that:
let frame = seriesListToFrame seriesList
returns frame as Frame, while seriesList is instead (string *Series<DateTime, float>) list
I think that the problem is with:
let seriesListMapper (colName:string, series:Series<'a, 'b>) =
[colName => series] |> frame
In fact seriesListMapper
is indicated as
seriesListMapper: colName:string * series:Series<'a, 'b> -> Frame<'a, string>
I do not understand how and why the values are converted to string
from float
.
One interesting thing is that plotting the frame with frame.Format()
actually confirms that the data looks correct. It is just this "strange" conversion to string
.
In the type annotation of the folderFnct
, you have aFrame:Frame
. However, the type representing data frames is a generic type with two type arguments (representing the type of index for rows and columns, respectively), so the annotation should be aFrame:Frame<_, _>
.
Another way to add series to a frame is to use mutating operation:
aFrame.AddSeries(colName, newSeries)
However, this only supports left join (data frame can only be mutated by adding new series, but not in a way that would change the index). However, you might be able to use this approach and then drop all missing values from the frame once it is constructed.
EDIT: To answer the question about generic types:
Series<K, V>
represents series with keys of typeK
containing values of typeV
(e.g. series with ordinarily indexed observations would haveK=int
andV=float
)Frame<R, C>
represents a frame that contains heterogeneous data (of potentially varying types for each column) where the rows are indexed byR
and columns are indexed byC
. For ordinarily indexed frameR=int
and typically, your columns will be named soC=string
(but you can have other indices too)
这篇关于映射到Deedle框架的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!