Как условно объединить два фрейма данных эффективно - PullRequest
0 голосов
/ 04 января 2019

Я пытаюсь назначить соответствующее расписание и номер поездки для каждого пакета GPS на основе отметки времени GPS.Как я могу сделать это эффективно, поскольку у меня есть почти миллион GPS-пакетов от различных устройств?

Я не нашел оптимального способа.Сейчас я запускаю цикл по всем строкам и сравниваю его отметку времени со всеми интервалами в расписании, не направляю таблицу и прикрепляю соответствующие номера расписаний к каждому GPS-пакетам.

Кадр данных GPS:

import pandas as pd
gps_df = pd.DataFrame({'Device':[1,1,2,2,3,3,3],'time-stamp': ['6:00:00','7:00:30','12:12:12','13:13:13','20:15:10','22:16:10','22:18:23']})

Расписание данных фрейма: \ n

schedule_df = pd.DataFrame({'Device'    :[1,    1,  1,  1,  2,  2,  2,  3,3,    3],
'schedule'  :['A1','A1','A2','A2','B1','B2','B2','C1','C2','C3'],
'route no'  :[1,    2,  1,  2,  1,  5,  6,  1,  1,  2],
'start time' :  ['6:00:00','7:00:01','8:30:00','10:00:00','12:00:00','14:00:00','16:00:00','20:00:00','21:00:00','22:00:00'],
'end time'  :['7:00:00','8:30:00','9:30:00','12:00:00','13:00:00','16:00:00','20:00:00','21:00:00','22:00:00','23:00:00']})

Я хотел бы получить вывод, подобный этому:

gps_df = pd.DataFrame({'Device':[1,1,2,2,3,3,3],
                   'time-stamp':['6:00:00','7:00:30','12:12:12','13:13:13','20:15:10','22:16:10','22:18:23'],
                    'schedule': ['A1','A1','B1','Na','C1','C3','C3'],
                    'route':    [1, 2,  1,  'Na',1, 2,  2]})

Ответы [ 3 ]

0 голосов
/ 04 января 2019

Использование merge:

cols = ['Device', 'schedule', 'route','timestamp']
df = df2.merge(df1, on='Device')
df = df.loc[df.timestamp.lt(df.end_time) & df.timestamp.gt(df.start_time), cols]\
       .set_index(['timestamp','Device'])\
       .reindex(index=df1.set_index(['timestamp','Device']).index)\
       .reset_index()

print(df)
  timestamp  Device schedule  route
0  06:00:01       1       A1    1.0
1  07:00:30       1       A1    2.0
2  12:12:12       2       B1    1.0
3  13:13:13       2      NaN    NaN
4  20:15:10       3       C1    1.0
5  22:16:10       3       C3    2.0
6  22:18:23       3       C3    2.0

Или:

df = df.loc[df.timestamp.between(df.start_time,df.end_time), cols]\
       .set_index(['timestamp','Device'])\
       .reindex(index=df1.set_index(['timestamp','Device']).index)\
       .reset_index()
0 голосов
/ 04 января 2019

Вы можете попробовать использовать массивы numpy.Я пропустил некоторый код для инициализации дополнительных выходных столбцов, которые вы хотите добавить в свой кадр данных GPS, но, тем не менее, идея состоит в том, чтобы создать двумерный массив, где пересечение логики AND создает таблицу истинности, которая сопоставляет совпадения по идентификатору устройства.и время в пределах диапазона, так что «i» - это соответствующий индекс строки в GPS df, а «j» - соответствующий индекс строки в «Расписание» df.

gpsd = GPS_df.Device.values
schedd = Sched_df.Device.values

gpst = GPS_df.timestamp.values
tl = Sched_df.start_time.values
th = Sched_df.end_time.values

i, j = np.where((gpsd[None].T == schedd) & 
                (gpst[None].T >= tl ) &
                (gpst[None].T <= th))
GPS_df.loc[i,'schedule'] = Sched_df.loc[j,'schedule']
GPS_df.loc[i,'route'] = Sched_df.loc[j,'route']
0 голосов
/ 04 января 2019

Попробуйте: импортируйте панд как pd

gps_df = pd.DataFrame({'Device':[1,1,2,2,3,3,3],'time-stamp': ['6:00:00','7:00:30','12:12:12','13:13:13','20:15:10','22:16:10','22:18:23']})
schedule_df = pd.DataFrame({'Device'    :[1,    1,  1,  1,  2,  2,  2,  3,3,    3],
'schedule'  :['A1','A1','A2','A2','B1','B2','B2','C1','C2','C3'],
'route no'  :[1,    2,  1,  2,  1,  5,  6,  1,  1,  2],
'start time' :  ['6:00:00','7:00:01','8:30:00','10:00:00','12:00:00','14:00:00','16:00:00','20:00:00','21:00:00','22:00:00'],
'end time'  :['7:00:00','8:30:00','9:30:00','12:00:00','13:00:00','16:00:00','20:00:00','21:00:00','22:00:00','23:00:00']})
print(gps_df)
print(schedule_df)
gps_df = pd.concat([gps_df, schedule_df],sort=True)
gps_df = gps_df.drop('end time', axis=1)
print(gps_df)

Вывод

   Device time-stamp
0       1    6:00:00
1       1    7:00:30
2       2   12:12:12
3       2   13:13:13
4       3   20:15:10
5       3   22:16:10
6       3   22:18:23


   Device schedule  route no start time  end time
0       1       A1         1    6:00:00   7:00:00
1       1       A1         2    7:00:01   8:30:00
2       1       A2         1    8:30:00   9:30:00
3       1       A2         2   10:00:00  12:00:00
4       2       B1         1   12:00:00  13:00:00
5       2       B2         5   14:00:00  16:00:00
6       2       B2         6   16:00:00  20:00:00
7       3       C1         1   20:00:00  21:00:00
8       3       C2         1   21:00:00  22:00:00
9       3       C3         2   22:00:00  23:00:00


      Device time-stamp schedule route
0       1    6:00:00       A1     1
1       1    7:00:30       A1     2
2       2   12:12:12       B1     1
3       2   13:13:13       Na    Na
4       3   20:15:10       C1     1
5       3   22:16:10       C3     2
6       3   22:18:23       C3     2

Надеюсь, это поможет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...