python - 熊猫将公式应用于每一行并找到最小值
问题描述
我正在寻找一种有效的方法来应用公式,使用来自一个数据帧 (df1) 的单行的变量对另一个数据帧 (df2) 中的每一行,然后找到此操作的最小值并存储 df2 中的行这个最小值作为一个新的数据框(df3)出现。给出了示例输入/输出。
df1
Index X1 Y1 Z1
1 3 6 4
2 7 2 1
3 4 7 3
df2
Index X2 Y2 Z2
1 2 4 1
2 5 3 2
3 7 1 5
申请公式:
d = math.sqrt((X2-X1)**2 + (Y2-Y1)**2 + (Z2-Z1)**2)
如果要将此公式迭代地应用于 df2,其中 (X1, Y1, Z1) 来自 df1 row1 并且 (X2, Y2, Z2) 来自 df2 中的每一行以给出。
[out]
Index d
1 3.741
2 4.123
3 6.481
由于 df2 第 1 行中的 (X2, Y2, Z2) 提供了最低的 d 值,因此该行将保存到 df3 中,然后对 df1 中的每一行重复该过程。
df3
Index X2 Y2 Z2
1 2 4 1
*注意,df1 和 df2 的长度不同。如果这个问题看起来冗长,我很抱歉,我只是想尽可能清楚。
解决方案
scipy.spatial.distance.cdist
可以使用其默认的欧几里德距离度量来实现这一点:
from scipy.spatial.distance import cdist
df3 = df2.iloc[cdist(df1, df2).argmin(axis=1)]
cdist
返回一个(n1, n2)
整形数组,其中n1
和分别是和n2
中的行数。然后我们查看每行的最小距离的索引,看看是哪一行引起了它。然后从中选择这些,df1
df2
df2
iloc
df2
要得到
>>> df3
X2 Y2 Z2
Index
1 2 4 1
2 5 3 2
1 2 4 1
中间结果:
>>> cdist(df1, df2)
# first row is your calculations in the question, for example
array([[3.74165739, 4.12310563, 6.4807407 ],
[5.38516481, 2.44948974, 4.12310563],
[4.12310563, 4.24264069, 7. ]])
>>> cdist(df1, df2).argmin(axis=1)
array([0, 1, 0], dtype=int64)
即,对于 的第 0 行和第 2 行df1
,选择第 0 行df2
;对于 的第一行df1
,df2
选择 的第一行(0 索引)。
当您提醒时间-内存权衡时,这是一个 for 循环实现:
# will keep the minimum distance rows' indices
min_inds = []
# foreach row of `df1`...
for row1 in df1.values:
# these will keep track of min so-far
min_dist = np.inf
min_ind = None
# foreach row of `df2`...
for j, row2 in enumerate(df2.values):
# squared distance
dist = ((row1 - row2) ** 2).sum()
# is less than minimum so far?
if dist < min_dist:
# then update min distance and index
min_dist = dist
min_ind = j
# one row of `df1` finished; save its corresponding row's index
min_inds.append(min_ind)
# Now we form `df3` with `iloc` as before
df3 = df2.iloc[min_inds]
这给出了相同的结果,但可能更节省内存。
推荐阅读
- r - 具有动态列数量的 DT Shiny 中的 GrandTotal
- angular - 如何在 azure 中设置 nodejs 版本
- ios - 层删除swift 4
- git - Jenkins- 定期投票和参数化构建
- unit-testing - 使用 groovy.mock.interceptor 检查输入参数
- c# - 使用 C# 在 Azure 中审核 HTTP 调用的日志记录
- php - 学说:多重inversedBy关系
- sql - 为什么要在字段上使用 LEFT JOIN,然后在 WHERE 子句中将其过滤掉?
- git - 如何通过来自 Bitbucket Pipelines 的 cURL 调用 Plesk Git 扩展 webhook?
- javascript - 如何将 SSJS 数组转换为 CSJS