join - asof 加入 Julia 数据工具

标签 join julia

我希望做一些类似 Pandas 的事情 merge_asof 或 QuestDB 的 ASOF JOIN 在 Julia 。 至关重要的是,我还需要应用分组操作 .
我很乐意使用 Julia 的任何 Table.jl尊重工具。 DataFrame 的 leftjoin get 很接近,但需要精确的键匹配,并且不进行分组(据我所知)。 SplitApplyCombine.jl 的 leftgroupjoin 允许您传入自己的比较函数,但我不太明白如何使用该函数来指定“最近的小于”值或“最近的大于”值。
对于不需要分组的简单示例,在两个表上 leftright , 每个都有一列 time ,我可以使用像这样的函数

function find_nearest_before(val, data)
    findlast(x -> x <= val, data)
end

[find_nearest_before(t, right.time) for t in left.time]
这将使我获得 right 中的索引加入 left .但是,我不太明白如何将其与 group-by 放在一起。

编辑
添加示例以使问题更清楚。第一表sensor_pings当传感器看到某物时报告。第二表in_sensor_FOV告诉我们在给定时间,传感器的视场 (FOV) 中实际上是什么物体。假设一个传感器一次在其 FOV 中只有一个对象(相反不一定正确)。
julia> using TypedTables

julia> sensor_pings = Table(time=[4,5,7,8,9,10,11,13,15,16], sensor_id=[2,1,1,3,2,3,1,2,3,2])
Table with 2 columns and 10 rows:
      time  sensor_id
    ┌────────────────
 1  │ 4     2
 2  │ 5     1
 3  │ 7     1
 4  │ 8     3
 5  │ 9     2
 6  │ 10    3
 7  │ 11    1
 8  │ 13    2
 9  │ 15    3
 10 │ 16    2

julia> in_sensor_FOV = Table(time=[1.3,2.6,3.8,5.9,7.3,8.0,12.3,14.7], sensor_id=[3,1,2,3,2,2,3,1], object_in_sensor_FOV=[:a,:b,:c,:b,:c,:a,:c,:b])
Table with 3 columns and 8 rows:
     time  sensor_id  object_in_sensor_FOV
   ┌──────────────────────────────────────
 1 │ 1.3   3          a
 2 │ 2.6   1          b
 3 │ 3.8   2          c
 4 │ 5.9   3          b
 5 │ 7.3   2          c
 6 │ 8.0   2          a
 7 │ 12.3  3          c
 8 │ 14.7  1          b
所需操作的最终结果如下所示
julia> Table(time=[4,5,7,8,9,10,11,13,15,16], sensor_id=[2,1,1,3,2,3,1,2,3,2], object_in_sensor_FOV=[:c,:b,:b,:b,:a,:b,:b,:a,:c,:a])

Table with 3 columns and 10 rows:
      time  sensor_id  object_in_sensor_FOV
    ┌──────────────────────────────────────
 1  │ 4     2          c
 2  │ 5     1          b
 3  │ 7     1          b
 4  │ 8     3          b
 5  │ 9     2          a
 6  │ 10    3          b
 7  │ 11    1          b
 8  │ 13    2          a
 9  │ 15    3          c
 10 │ 16    2          a

最佳答案

写这样的东西很容易,你只需要实现双光标

using TypedTables
using Setfield

sensor_pings = Table(time=[4,5,7,8,9,10,11,13,15,16], sensor_id=[2,1,1,3,2,3,1,2,3,2])

in_sensor_FOV = Table(time=[1.3,2.6,3.8,5.9,7.3,8.0,12.3,14.7], sensor_id=[3,1,2,3,2,2,3,1], object_in_sensor_FOV=[:a,:b,:c,:b,:c,:a,:c,:b])

function mergeasof(t1, t2)
    objects = similar(t2.object_in_sensor_FOV, length(t1.time))
    d = ntuple(_ -> :z, 3) # :z is a sentinel value, means that there were no objects up to this moment. Can be anything
    i2 = 1
    # Double cursor
    for i1 in axes(t1, 1)
        tm1 = t1.time[i1]
        # updating `d` to the current time step 
        while i2 <= length(t2.time)
            t2.time[i2] > tm1 && break
            @set! d[t2.sensor_id[i2]] = t2.object_in_sensor_FOV[i2]
            i2 += 1
        end
        objects[i1] = d[t1.sensor_id[i1]]
    end

    return Table(time = t1.time, sensor_id = t1.sensor_id, object_in_sensor_FOV = objects)
end

julia> mergeasof(sensor_pings, in_sensor_FOV)
Table with 3 columns and 10 rows:
      time  sensor_id  object_in_sensor_FOV
    ┌──────────────────────────────────────
 1  │ 4     2          c
 2  │ 5     1          b
 3  │ 7     1          b
 4  │ 8     3          b
 5  │ 9     2          a
 6  │ 10    3          b
 7  │ 11    1          b
 8  │ 13    2          a
 9  │ 15    3          c
 10 │ 16    2          a
它应该相当快,并且可以适应任意数量的列(只是向右更乏味)。
不过笔记很少
  • 此函数期望表按 time 排序
  • 它可以适应前向搜索,但它可能更乏味。
  • 我正在使用有 3 个传感器的事实。如果事先知道传感器的数量,那么应该可以在ntuple中使用。功能。如果未知或大或索引是任意的,那么您可以使用 Dict
  • 代替 ntuple。
    d = Dict{Int, Symbol}()
    
    @set!应该删除
    d[t2.sensor_id[i2]] = t2.object_in_sensor_FOV[i2]
    
    而不是
    objects[i1] = d[t1.sensor_id[i1]]
    
    你应该使用
    objects[i1] = get(d, t1.sensor_id[i1], :z)
    

    关于join - asof 加入 Julia 数据工具,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66629351/

    相关文章:

    julia - 函数 Base.+ 必须显式导入才能扩展

    arrays - Julia:一种从数组数组中获取矩阵的快速而优雅的方法

    json - 在 Julia 中是否值得对 `JSON.parsefile` 返回的字典进行类型缩小

    task - 如何在Julia中杀死任务/协程?

    mysql - 如果在表中找不到数据字段,则返回值 0 或 0.00 - MySql

    Mysql:一个表的一个字段和另一个表的两个字段之间的多重关系

    perl - 当标题匹配多个文件时连接列值

    julia - Julia 中的可拖动轴 slider

    mysql - 连接两个集合并在 MongoDB 中更新

    php - MySQL:JOIN 和条件语句