Power BI - 匹配两个表中最接近的 3D 点
Power BI - Matching closest 3D points from two tables
我有两个tables(Table 1和Table 2)都包含数千个三维点坐标(X,Y,Z),Table 2还有一个属性列。
Table 1
X
Y
Z
6007
44268
1053
6020
44269
1051
Table 2
X
Y
Z
Attribute
6011
44310
1031
A
6049
44271
1112
B
我需要根据 3D space 中点之间的最小距离,使用 Table 2 中的属性填充 Table 1 中的计算列。基本上,将 Table 1 中的点与 Table 2 中的最近点匹配,然后从 Table 2.
中获取属性
到目前为止,我已尝试在两个 table 中对 X、Y 和 Z 进行四舍五入,然后将四舍五入的值连接到每个 table 中的单独列中。然后我使用 DAX:
CALCULATE(FIRSTNONBLANK(Table 2 [Attribute],1),FILTER(ALL(Table2), Table 2[XYZ]=Table 1 [XYZ])).
根据应用于坐标的舍入程度,这给了我合理的成功。
在 Power Bi 中是否有更好的方法来实现此目的?
这类似于 , except with a simpler distance function. See also 。
假设您想要标准 Euclidean Distance:
ClosestPointAttribute =
MINX (
TOPN (
1,
Table2,
( Table2[X] - Table1[X] ) ^ 2 +
( Table2[Y] - Table1[Y] ) ^ 2 +
( Table2[Z] - Table1[Z] ) ^ 2,
ASC
),
Table2[Attribute]
)
注意:我从公式中省略了 SQRT,因为我们不需要实际距离,只需要排序(SQRT 保留顺序,因为它是一个 strictly increasing 函数)。如果您愿意,可以包括它。
M代码中的一个函数:
(p1 as list, q1 as list)=>
let
f = List.Generate(
()=> [x = Number.Power(p1{0}-q1{0},2), idx=0],
each [idx]<List.Count(p1),
each [x = Number.Power(p1{[idx]+1}-q1{[idx]+1},2), idx=[idx]+1],
each [x]
),
r = Number.Sqrt(List.Sum(f))
in
r
每个列表都是一组坐标,函数将 return p
和 q
之间的距离
以上函数(我命名为fnDistance
)可以合并到电源查询代码中,如本例所示:
let
//Read in both tables and set data types
Source2 =Excel.CurrentWorkbook(){[Name="Table_2"]}[Content],
table2 = Table.TransformColumnTypes(Source2,{{"X", Int64.Type}, {"Y", Int64.Type}, {"Z", Int64.Type},{"Attribute", Text.Type}}),
Source = Excel.CurrentWorkbook(){[Name="Table_1"]}[Content],
table1 = Table.TransformColumnTypes(Source,{{"X", Int64.Type}, {"Y", Int64.Type}, {"Z", Int64.Type}}),
//calculate distances from Table 1 coordinates to each of the Table 2 coordinates and store in a List
custom = Table.AddColumn(table1,"Distances", each
let
t2 = Table.ToRecords(table2),
X=[X],
Y=[Y],
Z=[Z],
distances = List.Generate(()=>
[d=fnDistance({X,Y,Z},{t2{0}[X],t2{0}[Y],t2{0}[Z]}),a=t2{0}[Attribute], idx=0],
each [idx] < List.Count(t2),
each [d=fnDistance({X,Y,Z},{t2{[idx]+1}[X],t2{[idx]+1}[Y],t2{[idx]+1}[Z]}),a=t2{[idx]+1}[Attribute], idx=[idx]+1],
each {[d],[a]}),
//determine set of coordinates with the minimum distance and return associate Attribute
minDistance = List.Min(List.Alternate(List.Combine(distances),1,1,1)),
attribute = List.Range(List.Combine(distances), List.PositionOf(List.Combine(distances),minDistance)+1,1){0}
in
attribute, Text.Type)
in
custom
我有两个tables(Table 1和Table 2)都包含数千个三维点坐标(X,Y,Z),Table 2还有一个属性列。
Table 1
X | Y | Z |
---|---|---|
6007 | 44268 | 1053 |
6020 | 44269 | 1051 |
Table 2
X | Y | Z | Attribute |
---|---|---|---|
6011 | 44310 | 1031 | A |
6049 | 44271 | 1112 | B |
我需要根据 3D space 中点之间的最小距离,使用 Table 2 中的属性填充 Table 1 中的计算列。基本上,将 Table 1 中的点与 Table 2 中的最近点匹配,然后从 Table 2.
中获取属性到目前为止,我已尝试在两个 table 中对 X、Y 和 Z 进行四舍五入,然后将四舍五入的值连接到每个 table 中的单独列中。然后我使用 DAX:
CALCULATE(FIRSTNONBLANK(Table 2 [Attribute],1),FILTER(ALL(Table2), Table 2[XYZ]=Table 1 [XYZ])).
根据应用于坐标的舍入程度,这给了我合理的成功。
在 Power Bi 中是否有更好的方法来实现此目的?
这类似于
假设您想要标准 Euclidean Distance:
ClosestPointAttribute =
MINX (
TOPN (
1,
Table2,
( Table2[X] - Table1[X] ) ^ 2 +
( Table2[Y] - Table1[Y] ) ^ 2 +
( Table2[Z] - Table1[Z] ) ^ 2,
ASC
),
Table2[Attribute]
)
注意:我从公式中省略了 SQRT,因为我们不需要实际距离,只需要排序(SQRT 保留顺序,因为它是一个 strictly increasing 函数)。如果您愿意,可以包括它。
M代码中的一个函数:
(p1 as list, q1 as list)=>
let
f = List.Generate(
()=> [x = Number.Power(p1{0}-q1{0},2), idx=0],
each [idx]<List.Count(p1),
each [x = Number.Power(p1{[idx]+1}-q1{[idx]+1},2), idx=[idx]+1],
each [x]
),
r = Number.Sqrt(List.Sum(f))
in
r
每个列表都是一组坐标,函数将 return p
和 q
以上函数(我命名为fnDistance
)可以合并到电源查询代码中,如本例所示:
let
//Read in both tables and set data types
Source2 =Excel.CurrentWorkbook(){[Name="Table_2"]}[Content],
table2 = Table.TransformColumnTypes(Source2,{{"X", Int64.Type}, {"Y", Int64.Type}, {"Z", Int64.Type},{"Attribute", Text.Type}}),
Source = Excel.CurrentWorkbook(){[Name="Table_1"]}[Content],
table1 = Table.TransformColumnTypes(Source,{{"X", Int64.Type}, {"Y", Int64.Type}, {"Z", Int64.Type}}),
//calculate distances from Table 1 coordinates to each of the Table 2 coordinates and store in a List
custom = Table.AddColumn(table1,"Distances", each
let
t2 = Table.ToRecords(table2),
X=[X],
Y=[Y],
Z=[Z],
distances = List.Generate(()=>
[d=fnDistance({X,Y,Z},{t2{0}[X],t2{0}[Y],t2{0}[Z]}),a=t2{0}[Attribute], idx=0],
each [idx] < List.Count(t2),
each [d=fnDistance({X,Y,Z},{t2{[idx]+1}[X],t2{[idx]+1}[Y],t2{[idx]+1}[Z]}),a=t2{[idx]+1}[Attribute], idx=[idx]+1],
each {[d],[a]}),
//determine set of coordinates with the minimum distance and return associate Attribute
minDistance = List.Min(List.Alternate(List.Combine(distances),1,1,1)),
attribute = List.Range(List.Combine(distances), List.PositionOf(List.Combine(distances),minDistance)+1,1){0}
in
attribute, Text.Type)
in
custom