如何将数据框中的一行的值与另一个数据框中的多行进行比较(包括计算)
Posted
技术标签:
【中文标题】如何将数据框中的一行的值与另一个数据框中的多行进行比较(包括计算)【英文标题】:How to compare the values of a row in a data frame with multiple rows from another data frame (include calculation) 【发布时间】:2020-12-22 16:27:15 【问题描述】:抱歉,因为写标题的英文不好。我想做的是通过与另一个数据框df2
进行比较来确定df
的位置。
df
是一个数据框,显示了一段时间内经纬度的变化。它是一个包含超过 40,000 行的数据框。
df=
Longitude Latitude
Time
2020-01-01 01:00 100.0 20.0
2020-01-01 01:01 100.2 20.1
2020-01-01 01:02 300.1 30.0
2020-01-01 01:03 200.1 40.0
2020-01-01 01:04 50.0 50.0
df2
是包含位置数据的数据框。它是一个大约 30 行的数据框。
df2=
Longitude Latitude Location
0 90.0 20.0 District A
1 210.0 60.0 District B
确定我所在位置的方法将由毕达哥拉斯定理完成。 df
中的每一行数据都会与df2
中的每一行数据进行比较,找出最短距离,最短的距离就是我所在的位置。
以2020-01-01 01:01
为例。
首先,与df2 row 0
比较,计算为[(100.2-90.0)^2+(20.1-20.0)^2]^0.5
。
其次,与df2 row 1
比较,计算为[(100.2-210.0)^2+(20.1-60.0)^2]^0.5
由于位置与District A
之间的距离小于位置与District B
之间的距离,因此2020-01-01 01:01
上的位置将为District A
。预期输出如下。
df=
Longitude Latitude Location
Time
2020-01-01 01:00 100.0 20.0 District A
2020-01-01 01:01 100.2 20.1 District A
2020-01-01 01:02 300.1 30.0 District B
2020-01-01 01:03 200.1 40.0 District B
2020-01-01 01:04 50.0 50.0 District A
我的方法:为了首先得到我的预期结果,我将创建一个充满NaN
的df['Loaction']
列,然后我将进行计算并提取df2['Location']
以替换NaN
中的NaN
值df['Loaction']
。
但是,我很困惑的是如何获得计算结果。是否有任何相关的 pandas 函数或 NumPy 函数可以将df
中的一行与df2
中的多行进行比较?有更好的方法吗?谢谢!
【问题讨论】:
【参考方案1】:我忽略了时间列,因为不需要任何操作。
d = 'Longitude': [100.0,100.2,300.1,200.1,50.0], 'Latitude': [20.0 , 20.1,30.0,40.0, 50.0 ]
df = pd.DataFrame(data=d)
d2 = 'Longitude':[90.0, 210.0], 'Latitude':[20.0, 60.0], 'Location':['District A', 'District B']
df2 = pd.DataFrame(data=d2)
一个 lambda 函数可以逐行应用于 df,因为我们将 df 的每一行与 df2 的所有行进行比较。它不是一对一的映射。
所以,首先我尝试找到最小距离,然后从 df2 获取“位置”值。请注意,我避免在距离计算中采用 sqrt 值以简化解决方案。无论如何都应该无所谓,因为只需要最低限度。
df.apply(lambda x: df2['Location'][(x[0] - df2['Longitude'])**2 + (x[1] - df2['Latitude'])**2 == min((x[0] - df2['Longitude'])**2 + (x[1] - df2['Latitude'])**2)].iloc[0], axis=1)
这应该会产生以下输出。
df.apply(lambda x: df2['Location'][(x[0] - df2['Longitude'])**2 + (x[1] - df2['Latitude'])**2 == min((x[0] - df2['Longitude'])**2 + (x[1] - df2['Latitude'])**2)].iloc[0], axis=1)
0 District A
1 District A
2 District B
3 District B
4 District A
dtype: object
如果将最后一列添加到 df,则如下所示。
>>> df['Location'] = df.apply(lambda x: df2['Location'][(x[0] - df2['Longitude'])**2 + (x[1] - df2['Latitude'])**2 == min((x[0] - df2['Longitude'])**2 + (x[1] - df2['Latitude'])**2)].iloc[0], axis=1)
>>>
>>> df
Longitude Latitude Location
0 100.0 20.0 District A
1 100.2 20.1 District A
2 300.1 30.0 District B
3 200.1 40.0 District B
4 50.0 50.0 District A
【讨论】:
如果解决方案令人满意,也请接受正确的答案。它是upvote按钮下方的刻度线。 我已经尝试过您的示例,它运行良好。但是当我应用到我的代码时,它给出了一个错误:试图在 DataFrame 的切片副本上设置一个值。所有 df['Location'] 都更改为 'District A'。我已经研究了一段时间,但我不明白 lambda 是如何不起作用的,因为我的 df 是一个副本 恐怕,我需要更多详细信息,例如您编写的代码。但是,这似乎是对已返回副本的数据框执行选择,然后当我们尝试在此副本上设置时,返回错误。你检查过这个线程吗? ***.com/questions/20625582/… 另外,如果答案解决了发布的问题,请接受正确的答案。以上是关于如何将数据框中的一行的值与另一个数据框中的多行进行比较(包括计算)的主要内容,如果未能解决你的问题,请参考以下文章