Выполнить слияние на основе совпадения подстроки?

Хотя этот вопрос тесно связан с слиянием нечетких совпадений с пандами, этот вопрос конкретно касается только слияния (или подмножества, в данном случае), когда ключ в одном DataFrame полное совпадение или подстрока ключа в другом DataFrame, Чтобы проиллюстрировать мою точку зрения, вот 2 DataFrames:

df1
   id   code
0   1   E282
1   2  O0080
2   3    R52
3   4  J0100
4   5    F99

df2
    code  val
0   V282   11
1   O008   12
2  J0101   13
3    F99   14
4    R55   15

Проблема с использованием difflib в том, что я действительно не хочу сопоставлять ближайшую строку, и я не уверен, что смогу разделить совпадения как V282 в E282, чего не должно случиться и подобного O008 в O0080 который должен слиться.

Ожидаемый результат должен быть

   code1  id
0  O0080   2
1    F99   5

Я могу добраться до этого результата с

import numpy as np
df1[np.logical_or.reduce([df1['code'].str.contains(code) for code in df2.code.tolist()])]

но с тех пор df1 длиной 42M и df2 содержит ~4000 кодов, этот метод невероятно медленный. Это лучшее, что я собираюсь сделать? Просто кажется прискорбным, когда внутреннее объединение строки 21M df и строки 7M df для точных ключей занимает < 1 минуту.

1 ответ

Решение

Это сложная проблема. Может быть, рассмотреть подход Python? any здесь будет короткое замыкание, поэтому вы должны сэкономить на некоторых циклах. Также, contains не обязательно проверять с самого начала, поэтому использование startswith вместо этого должен быть более эффективным.

df1[
    any(
         i.startswith(j) for j in df2.codes.tolist()
    ) for i in df1.codes.tolist()
]

Что о:

import pandas as pd

df1 = pd.DataFrame({'id':[1,2,3,4,5], 'code':['E282', 'O0080', 'R52', 'J0100', 'F99']})
df2 = pd.DataFrame({'code':['V282','O008','J0101','F99','R55'], 'val':[11,12, 13, 14, 15]})

pat = "|".join(df2['code'])
df1.insert(0, 'part_code', df1['code'].str.extract("(" + pat + ')', expand=False))
pd.merge(df1, df2, how='inner', left_on='part_code', right_on='code')[['code_y', 'id']]

На основе /questions/5098695/python-pandas-obedinenie-na-osnove-podstroki-v-stroke/5098698#5098698

Другие вопросы по тегам