python - 如何检查数据框 B 中第 1 列的值是否介于数据框 A 中第 1 列和第 2 列的值之间。如果为真,则返回数据框 A 的第 2 列
问题描述
我有两个数据框。数据框 A 有五列:start_time、end_time、ID_user、ID_position 和orientation。Dataframe B 有四列:timestamp、ID_user、ID_sender 和 RSSI。
我想将数据帧A的ID_position列添加到数据帧B,所以我知道哪个RSSI值(数据帧B)对应于哪个ID_position(数据帧A)。为此,我需要知道某人在何时何地。所以我需要检查时间戳位于哪个 start_time 和哪个 end_time (数据帧 A)之间(数据帧 B)。总共有277个职位。
简单来说:如果时间戳(数据帧 B)在开始时间和结束时间(数据帧 A)之间,则将 ID_position 返回到相应的时间戳,并将其作为列添加到数据帧 B。
我在许多网站上搜索并尝试了很多东西,但这可能是我想出的最好的:我将列更改为 tolist() 因为列表的处理速度比列快。我尝试在函数中使用 for 循环来检查开始时间和时间戳并进行比较。我没有使用开始时间和结束时间,而是尝试只使用开始,因为这会减少 for 循环(但使用结束时间更好)。我尝试了合并、分配等,但无法弄清楚。我最有希望的解决方案放在下面。第一个解决方案导致一个时间戳的 ID_positions 列表,而不是一个位置。
def position (timestamp):
pos_list = []
pos = survey.ID_position
time = 1540648136288
for t in range(len(timestamp)):
if (timestamp[t] <= time):
pos_list.append(pos)
elif (timestamp[t] > time):
time = time + 8000
pos = survey.ID_position + 1
return(pos_list)
def numbers2 (position):
pos_ID = []
post_list = []
for i in range(len(position)):
pos_ID.append(position[i])
def num_pos2(timestamp):
pos_list = []
pos = ID
time = 1540648127883
for t in range(len(timestamp)):
if (time <= timestamp[t] <= (time+8000)):
pos_list.append(pos[i])
if timestamp[t] > time:
pos_list.append(pos[i+1])
time = time + 8000
position = pos[i+1]
return(pos_list)
Dataframe A(前几行,1108行×5列,共277个位置)
start_time end_time ID_user ID_position orientation
0 1540648127883 1540648129883 1 1 1
1 1540648129884 1540648131883 1 1 2
2 1540648131884 1540648133883 1 1 3
3 1540648133884 1540648136288 1 1 4
4 1540648179559 1540648181559 1 2 1
5 1540648181560 1540648183559 1 2 2
6 1540648183560 1540648185559 1 2 3
7 1540648185560 1540648187846 1 2 4
8 1540648192618 1540648194618 1 3 1
9 1540648194619 1540648196618 1 3 2
10 1540648196619 1540648198618 1 3 3
11 1540648198619 1540648201336 1 3 4
数据框 B(前几行,209393 行 × 4 列)
timestamp ID_user ID_sender RSSI
0 1540648127974 1 1080 -95
1 1540648128037 1 1 -51
2 1540648128076 1 1080 -95
3 1540648128162 1 1 -53
4 1540648128177 1 1080 -95
预期结果数据框 B:
timestamp ID_user ID_sender RSSI ID_position
0 1540648127974 1 1080 -95 1
1 1540648128037 1 1 -51 1
2 1540648128076 1 1080 -95 1
3 1540648128162 1 1 -53 1
4 1540648128177 1 1080 -95 1
.......................... < a lot of rows between >
1809 1540648179571 1 1080 -75 2
1810 1540648179579 1 1 -55 2
1811 1540648179592 1 1070 -96 2
1812 1540648179627 1 1069 -100 2
1813 1540648179669 1 1080 -78 2
1814 1540648179772 1 1080 -79 2
总数据集可以在:http ://wnlab.isti.cnr.it/localization
我想检查数据帧 B 的时间戳在哪个开始时间和结束时间(数据帧 A)之间,并且我想返回数据帧 A 的 ID_position。所以最后,数据帧 B 有一列 ID_positions 对应于正确的时间戳。例如:如果开始时间为 1,结束时间为 4,并且 ID_position 为 1。我想为时间戳 3 获取 ID_position 1,因为它介于 1 和 4 之间。
先感谢您!
解决方案
您可以outer merge
使用两个数据框来ID_user
返回many-to-many
产品(因此这些都是组合,例如笛卡尔积)。
query
然后我们用on过滤start_time < timestamp < end_time
:
df = pd.merge(dfB, dfA, on='ID_user', how='outer')\
.query('start_time < timestamp < end_time')\
.drop(['start_time', 'end_time', 'orientation'], axis=1)\
.reset_index(drop=True)
输出
print(df)
timestamp ID_user ID_sender RSSI ID_position
0 1540648127974 1 1080 -95 1
1 1540648128037 1 1 -51 1
2 1540648128076 1 1080 -95 1
3 1540648128162 1 1 -53 1
4 1540648128177 1 1080 -95 1
请注意,我没有在<
运算符中使用包含。<=
如果需要,您可以将其更改为。
note2如果您的数据框很大。这将消耗内存,请参阅many-to-many
上面的解释。
在 OP 对多个职位发表评论后进行编辑
我仍然得到正确的结果。
# Print the new used dataframes
print(dfA, '\n')
print(dfB, '\n')
start_time end_time ID_user ID_position orientation
0 1540648127883 1540648129883 1 1 1
1 1540648129884 1540648131883 1 1 2
2 1540648131884 1540648133883 1 1 3
3 1540648133884 1540648136288 1 1 4
4 1540648179559 1540648181559 1 2 1
5 1540648181560 1540648183559 1 2 2
6 1540648183560 1540648185559 1 2 3
7 1540648185560 1540648187846 1 2 4
8 1540648192618 1540648194618 1 3 1
9 1540648194619 1540648196618 1 3 2
10 1540648196619 1540648198618 1 3 3
11 1540648198619 1540648201336 1 3 4
timestamp ID_user ID_sender RSSI
0 1540648127974 1 1080 -95
1 1540648128037 1 1 -51
2 1540648128076 1 1080 -95
3 1540648128162 1 1 -53
4 1540648128177 1 1080 -95
5 1540648179571 1 1080 -75
6 1540648179579 1 1 -55
7 1540648179592 1 1070 -96
8 1540648179627 1 1069 -100
9 1540648179669 1 1080 -78
10 1540648179772 1 1080 -79
df = pd.merge(dfB, dfA, on='ID_user', how='outer')\
.query('start_time < timestamp < end_time')\
.drop(['start_time', 'end_time', 'orientation'], axis=1)\
.reset_index(drop=True)
print(df)
timestamp ID_user ID_sender RSSI ID_position
0 1540648127974 1 1080 -95 1
1 1540648128037 1 1 -51 1
2 1540648128076 1 1080 -95 1
3 1540648128162 1 1 -53 1
4 1540648128177 1 1080 -95 1
5 1540648179571 1 1080 -75 2
6 1540648179579 1 1 -55 2
7 1540648179592 1 1070 -96 2
8 1540648179627 1 1069 -100 2
9 1540648179669 1 1080 -78 2
10 1540648179772 1 1080 -79 2
推荐阅读
- openshift - 如何在 Openshift 中从 qemu-kvm img 文件和自定义内核创建 VM?
- python - Python:在 Plotly 的子图中共享图例
- python - ImageDataBunch 函数未定义-FastAI windows
- html - 文本对齐问题:在具有“值”属性的输入元素上
- c# - 我在 Azure Function Monitor 日志屏幕中看到了条目。如何在 Application Insights 中找到它们?
- heroku - 如何在没有 package.json 的情况下部署到 heroku 简单网站
- angular - 如何限制角材质CDK拖放元素在某个轴上的拖动范围?
- ios - 在后台获取苹果健康数据
- postgresql - Postgresql比较同一张表上的两个选择结果
- javascript - 当所有预取链接都准备好时如何通知?