Сравните несколько python pandas фреймов данных для общих строк на основе сопоставления нескольких столбцов на основе определенных критериев - PullRequest
0 голосов
/ 06 марта 2020

У меня есть два DataFrames, которые имеют более 100 000 строк, которые могут иметь разную длину и различное количество столбцов. Я хочу знать, какие строки в DF1 совпадают со строками в DF2, когда столбцы A и B совпадают между двумя фреймами данных, а столбец C находится в пределах 1 минуты друг от друга. Тем не менее, в столбцах A и B может быть несколько экземпляров спаривания со случайными индексами по всем кадрам данных, поэтому я не думаю, что простое слияние работает. Кроме того, вы можете увидеть несколько пар с одним и тем же временем, поэтому вы не можете обязательно объединить их. Пожалуйста, посмотрите пример ниже:

DF1

A     B            Time             D
45   100   2013-07-10  00:00:00   99522
45   100   2013-07-10  05:00:00   99522
10   350   2013-07-10  05:00:00   99522
45   100   2013-07-10  12:00:00   99522
10   350   2013-07-10  15:00:00   99522
36   900   2013-07-10  03:00:00   92222

DF2

A     B            Time             D
45   100   2013-07-10  00:00:56   99522
10   350   2013-07-10  15:05:00   99522
36   900   2013-07-10  03:00:10   99522
45   100   2013-07-10  05:01:00   99522

И я хочу, чтобы результат имел DF1 с дополнительным столбцом и либо 1 или 0, указывающий, находится ли строка в DF1 в DF2 (1 = совпадение). Соответствующие строки имеют одинаковое соединение для столбцов A и B, а время в столбцах C находится в пределах 1 минуты друг от друга.

Result with DF1:

A     B            Time             D      MatchingRow
45   100   2013-07-10  00:00:00   99522        1
45   100   2013-07-10  05:00:00   99522        1
10   350   2013-07-10  05:00:00   99522        0
45   100   2013-07-10  12:00:00   99522        0
10   350   2013-07-10  15:00:00   99522        0
36   900   2013-07-10  03:00:00   99522        1

Я изначально нашел уникальные пары из DF1, как в (45/100 или 10/350), циклически проходящие через каждую пару и фильтрующие каждый DataFrame, но выполнение кода занимает очень много времени, и я хочу избежать циклов с DataFrames

Вот что я сделал перед использованием кода psuedo:

for pair in unique_pairs:
    obj1 = pair[0]
    obj2 = pair[1]

    # Filtering each dataframe to only the rows that have this pairing
    Dataframe1 = Dataframe1[Dataframe1[A] == obj1 and Dataframe1[B] == obj2]
    Dataframe2 = Dataframe2[Dataframe2[A] == obj1 and Dataframe2[B] == obj2]


    for row_DF1 in Dataframe1:
        MatchFlag = 0

        # for loop to see if the time in DF1 is within DF2 with a 1 minute tolerance
        for row_DF2 in Dataframe2: 
             diff  = abs(row_DF1[Time] - row_DF2[Time])
             if diff <= 1 # minute
                 print(Match!)
                 MatchFlag = 1
                 break
        # No matching time +/- 1 minute found
        if MatchFlag == 0:
            Print(No match for row_DF1)

Затем я нашел страницу stackoverflow и этот код:

df[np.isclose(df['A'].values[:, None], [3, 6], atol=.5).any(axis=1)]

Это сближает меня с находя похожие времена, но я не знаю, как реализовать это, не используя циклы for для фильтрации до заданного c анализа и прохода строка за строкой через DF1. Есть ли способ найти общие строки без всех циклов for?

Спасибо!

...