#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 в последней строке. Очень незначительная проблема.