Найдите строку в одной и той же последовательности среди нескольких кадров данных

#python #pandas #dataframe #sequence

Вопрос:

Я хочу найти одинаковые последовательности и их строки среди нескольких фреймов данных pandas по столбцу.

Например, найдите их в столбце 3.

Таблица А

 column1, column2, column3
 1,         a,      p1 
 2,         c,      p3
 3,         d,      P4
 4,         b,      p2
 

Таблица В

 column1, column2, column3
 1,         x,      p20 
 2,         x,      p20 
 3,         y,      p3
 4,         z,      P4
 5,         w,      p7
 

Вы можете видеть, что P3 и P4 находятся в одном и том же расположении в обеих таблицах. Я хочу определить и выбрать их строки соответственно. Пожалуйста, учтите, что у меня более 100 таблиц, что они должны использоваться не только для этих двух.

Кто-нибудь может мне помочь? Спасибо!

Комментарии:

1. Вы имеете в виду, что вам нужно найти последовательности «таблицы А» во всех других таблицах, или вы имеете в виду, что вам нужно найти соответствующие последовательности в ЛЮБОЙ паре таблиц? Сколько строк (обычно) в каждой таблице?

2. В данном случае любой стол. Это не обязательно должны быть p3 и p4. Это может быть «кошка, собака, хорек», если они присутствуют за двумя столами.

3. Ну, здесь нет короткого пути. Это грубая сила. С 100 столами у вас будет 5000 пар для проверки. Если в каждой из них 1000 строк, это 500 000 последовательностей на таблицу. Это можно сделать, но это займет некоторое время.

Ответ №1:

Вот код, который делает то, что вы хотите. В этом случае я сгенерировал 40 случайных столбцов со 100 записями и поискал совпадения последовательностей. Поскольку итерации pandas очень медленные, вы можете захотеть извлечь этот последний столбец из каждой таблицы в отдельный список списков.

 import numpy as np

def findall(row, value):
    for i,v in enumerate(row):
        if v == value:
            yield i

table_list = list( np.random.randint(0,25,size=100) for _ in range(40))

# For each table in the list:
for idxA, tblA in enumerate(table_list):
    # For each remaining table:
    for idxB, tblB in enumerate(table_list[idxA 1:]):
        # For each starting point in the first table:
        for a0 in range(len(tblA)-1):
            # Search for that value.
            for b0 in findall( tblB, tblA[a0] ):
                match = 1
                # Count how long the match is.
                a99 = len(tblA) - a0
                b99 = len(tblB) - b0
                for dx in range(min(a99,b99)):
                    if tblA[a0 dx] != tblB[b0 dx]:
                        break
                    match  = 1
                if match > 2:
                    print( f"Sequence of {match} at table {idxA} row {a0} and table {idxB idaX 1} row {b0}" )
 

Комментарии:

1. Спасибо! Это работает очень хорошо, исключая idaX в последней строке. Очень незначительная проблема.