Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
F# 如何在Deedle中对非唯一列/索引执行左联接_F#_Pandas_Deedle - Fatal编程技术网

F# 如何在Deedle中对非唯一列/索引执行左联接

F# 如何在Deedle中对非唯一列/索引执行左联接,f#,pandas,deedle,F#,Pandas,Deedle,我试图在Deedle中的两个数据帧之间进行左连接。两个数据帧的示例如下: let workorder= 柱的框架[ “workOrderCode”=?>系列[(2005020050);(2005120051);(2006020060)] “工作指令说明”=?>系列[(20050,“车门维修”);(20051,“升降机更换”);(20060,“车窗清洁”)] //由于工单代码重复,因此无法编译 设workOrderScores= 柱的框架[ “workOrderCode”=>系列[(2005020

我试图在Deedle中的两个数据帧之间进行左连接。两个数据帧的示例如下:

let workorder=
柱的框架[
“workOrderCode”=?>系列[(2005020050);(2005120051);(2006020060)]
“工作指令说明”=?>系列[(20050,“车门维修”);(20051,“升降机更换”);(20060,“车窗清洁”)]
//由于工单代码重复,因此无法编译
设workOrderScores=
柱的框架[
“workOrderCode”=>系列[(2005020050);(2005020050);(2005120051)]
“运行时”=>系列[(200502100112);(200502010130);(2005120100215)]
“分数”=>系列[(20050100);(20050120);(20051,80)]]
Frame.join JoinKind.Outer workOrders workOrders cores
问题是Deedle不允许我创建具有非唯一索引的数据帧,我得到以下错误:System.ArgumentException:重复键“20050”。索引中不允许有重复的键

有趣的是,在Python/Pandas中,我可以完成以下完美的工作。如何在Deedle中重现此结果?我在想,我可能必须展平第二个数据帧,以删除重复的数据帧,然后加入,然后取消填充/取消堆叠它

workOrders=pd.DataFrame(
{'workOrderCode':[200502005120060],
“workOrderDescription:[“车门维修”、“升降机更换”、“车窗清洁”]]
workOrderScores=pd.DataFrame(
{'workOrderCode':[200502005020051],
“运行时”:[20100112、20100130、20100215],
‘得分’:[100、120、80]})
pd.merge(workOrders,workOrderScores,on='workOrderCode',how='left')
#结果:
#workOrderCode workOrderDescription运行时分数
#0 20050车门维修20100112 100
#1 20050车门维修20100130 120
#2 20051升降机的更换2010021580
#3 20060擦窗楠楠楠楠

这是一个很好的问题-我必须承认,目前没有一种优雅的方法可以用Deedle做到这一点。能否请您向GitHub提交一个问题,以确保我们跟踪此问题并添加一些解决方案

正如您所说,Deedle目前不允许在键中有重复的值—尽管您的Pandas解决方案也不使用重复的键—您只需使用Pandas允许您在加入时指定要使用的列这一事实(我认为这对Deedle来说是一个很好的补充)

这里有一种方法可以做你想做的事——但不是很好。我认为使用数据透视是另一种选择(在最新的源代码中有一个很好的数据透视表函数,但在NuGet上还没有)

我使用
groupByRows
nest
将数据帧转换为按
workOrderCode
分组的系列(每个项目现在包含一个包含所有具有相同工单代码的行的帧):

现在我们可以加入这两个系列(因为它们的工单代码是键)。但是,对于每个连接的订单代码,您将获得一个或两个数据帧,并且需要大量的工作来外部连接两个帧的行:

// Join the two series to align frames with the same work order code
Series.zip workOrders workOrderScores
|> Series.map(fun _ (orders, scores) -> 
    match orders, scores with
    | OptionalValue.Present s1, OptionalValue.Present s2 ->
        // There is a frame with some rows with the specified code in both 
        // work orders and work order scores - we return a cross product of their rows
        [ for r1 in s1.Rows.Values do
          for r2 in s2.Rows.Values do 
          // Drop workOrderCode from one series (they are the same in both)
          // and append the two rows & return that as the result
          yield Series.append r1 (Series.filter (fun k _ -> k <> "workOrderCode") r2) ]
        |> Frame.ofRowsOrdinal
    // If left or right value is missing, we just return the columns
    // that are available (others will be filled with NaN)
    | OptionalValue.Present s, _ 
    | _, OptionalValue.Present s -> s)
|> Frame.unnest
|> Frame.indexRowsOrdinally
//连接两个系列以使用相同的工单代码对齐框架
Series.zip工作单工作单核心
|>系列地图(乐趣(订单,分数))->
与命令、分数相匹配
|可选值。当前s1,可选值。当前s2->
//有一个框架,其中的某些行在这两个框架中都具有指定的代码
//工单和工单分数-返回其行的叉积
[对于s1.Rows.Values中的r1
对于s2.Rows.Values中的r2
//从一个系列中删除workOrderCode(两个系列中的代码相同)
//并附加这两行&返回结果
收益率序列.append r1(序列.filter(fun k uk->k“workOrderCode”)r2)]
|>顺序框架
//如果缺少left或right值,则只返回列
//可用的(其他将填写NaN)
|可选值。当前值s,\u
|_u,可选值。显示s->s)
|>Frame.unnest
|>Frame.indexRowsOrdinally

这可能很慢(尤其是在NuGet版本中)。如果您正在处理更多数据,请尝试从源代码构建最新版本的Deedle(如果没有帮助,请提交一个问题-我们应该对此进行研究!)

谢谢您的回答。它似乎没有编译,因为缺少匹配的案例。我添加了大小写“| u,->frame[]),这似乎已经修复了它,但正如您所说的,性能不是很好。@jeremyh这应该只是一个警告(您可以忽略它,因为您永远不会在两侧都丢失值)。但是您的修复是避免警告的一个很好的方法(我也会在生产代码中这样做,以确保我没有留下任何无法解释的警告!)哦,是的,您的警告是正确的。当我输入更大的数据集时,警告会立即返回,而结果会延迟。我以为它会阻止结果返回,但它仍在后台运行。为此,我将在github上添加一个问题。
// Join the two series to align frames with the same work order code
Series.zip workOrders workOrderScores
|> Series.map(fun _ (orders, scores) -> 
    match orders, scores with
    | OptionalValue.Present s1, OptionalValue.Present s2 ->
        // There is a frame with some rows with the specified code in both 
        // work orders and work order scores - we return a cross product of their rows
        [ for r1 in s1.Rows.Values do
          for r2 in s2.Rows.Values do 
          // Drop workOrderCode from one series (they are the same in both)
          // and append the two rows & return that as the result
          yield Series.append r1 (Series.filter (fun k _ -> k <> "workOrderCode") r2) ]
        |> Frame.ofRowsOrdinal
    // If left or right value is missing, we just return the columns
    // that are available (others will be filled with NaN)
    | OptionalValue.Present s, _ 
    | _, OptionalValue.Present s -> s)
|> Frame.unnest
|> Frame.indexRowsOrdinally