Как проверить, находятся ли значения столбца 1 в кадре данных между значениями столбца 1 и 2 в кадре данных A. Если значение равно true, вернуть столбец 2 кадра данных A - PullRequest
0 голосов
/ 25 апреля 2019

У меня есть два кадра данных. Кадр данных A имеет пять столбцов: время начала, время окончания, ID_user, ID_position и ориентация. Кадр данных B имеет четыре столбца: метка времени, ID_user, ID_sender и RSSI.

Я хочу добавить столбец ID_position в фрейме данных A в фрейм данных 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)

Фрейм данных 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

Я хочу проверить, между каким временем начала и времени окончания (фрейма данных A) находятся временные метки из фрейма данных B, и я хочу вернуть ID_position из фрейма данных A. Таким образом, в конце фрейм данных B имеет столбец с ID_positions соответствующие правильные метки времени. Например: если начальное время равно 1, а конечное время равно 4, а ID_position равно 1. Я хочу получить ID_position 1 для отметки времени 3, поскольку она находится в диапазоне от 1 до 4.

Заранее спасибо!

1 Ответ

0 голосов
/ 25 апреля 2019

Вы можете сделать outer merge с обоими кадрами данных на ID_user, что даст вам many-to-many продукт обратно (так что это все комбинации, например, декартово произведение).

Затем мы фильтруем с query на 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 выше.

Редактировать после комментария ОП о нескольких позициях

Я все еще получаю правильные результаты.

# 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...