我有两个数据框。数据框A具有五列:开始时间,结束时间,ID_用户,ID_位置和方向。数据框B具有四列:时间戳,ID_user,ID_sender和RSSI。
我想将数据帧A的ID_position列添加到数据帧B,所以我知道哪个RSSI值(数据帧B)对应于哪个ID_position(数据帧A)。为此,我需要知道某人什么时候在哪里。因此,我需要检查时间戳位于哪个开始时间和结束时间(数据帧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)
数据框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之间。
提前谢谢!
答案 0 :(得分:0)
您可以对ID_user
上的两个数据帧执行outer merge
,这将给您带来many-to-many
乘积(所以这些都是组合,例如笛卡尔乘积)。
然后我们在start_time < timestamp < end_time
上用query
进行过滤:
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
的说明。
我仍然得到正确的结果。
# 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