Pandas автомат c СОЕДИНЕНИЕ между двумя pandas фрейм данных - PullRequest
1 голос
/ 14 июля 2020

Кто-нибудь знает, как найти потенциальное соединение между двумя pandas кадрами данных?

например. Я хочу найти возможное совпадение между столбцами этих наборов данных

введите описание изображения здесь

Я разработал что-то вроде этого

from tqdm import tqdm
import numpy as np

def _check_na(df, col, threshold=0.9):
    return sum(df[col].isna()) > (1- threshold) * df.shape[0]

def _check_dtype(df1, df2, c1, c2):
    
    try:
        df1[c1] = df1[c1].astype(df2.dtypes[c2])
        return True
    except:
        return False

def _fast_intersect(df1, df2, c1, c2, perc=0.2, maxrows=1000):
    n = min(df1.shape[0], df2.shape[0])
    
    c=1
    if n>maxrows:
        c = len(np.intersect1d(df1[c1].sample(n= maxrows, random_state=0).astype(str).values, df2[c2].astype(str)) )
    
    if (c>0) or n<=maxrows:
            return len(np.intersect1d(df1[c1].astype(str).values, df2[c2].astype(str).values))
    
    return 0

def possible_join(df1, df2, threshold=0.8, verbose=0):
    
    n = min(df1.shape[0], df2.shape[0])
    
    for c1 in tqdm(df1.columns):
        
        if _check_na(df1, c1):
            if verbose>1:
                print('WARN: too many na',c1)
            continue
        
        for c2 in df2.columns:
            

            if not(_check_dtype(df1, df2, c1, c2)):
                if verbose>1:
                    print('WARN: incompatible type',c1, df1.dtypes[c1],c2, df2.dtypes[c2])
                continue
            
            if _check_na(df2, c2):
                if verbose>1:
                    print('WARN: too many na',c2)
                continue
                
            c = _fast_intersect(df1, df2, c1, c2)
            print(c)

            if (c>= threshold * n):
                print ('** MATCH **:', c1,'-',c2,':', c, c/n, '%')
            elif (c>= threshold * n /2):
                print ('** LOW MATCH **:',c1,'-',c2,':', c, c/n, '%')
                

_check_dtype проверка на совпадение потенциалов между типами данных

_check_na исключает столбцы с большим количеством NaN

_fast_intersect пробует быстрое соединение с небольшим количеством данных, если оно проходит, ищите полное соединение.

но это слишком медленно!

тест

d = {'col11': [1, 2], 'col21': ['3', '4']}
df1 = pd.DataFrame(data=d)

d = {'col12': [1, 3], 'col22': [3, 4]}
df2 = pd.DataFrame(data=d)

possible_join(df1, df2, threshold=0.6, verbose=2)

результат:

col21 и col22 со 100% полным соответствием

col11 и col12 с 50% низким соответствием

1 Ответ

4 голосов
/ 14 июля 2020

используйте этот фрагмент кода в _fast_intersect:

first_df = df1.sample(n= int(n * perc), random_state=0)
second_df = df2
return pd.merge(first_df, second_df, how="inner", on="c2").shape[0]

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...