Tengo dos marcos de datos que quiero fusionar en función de una coincidencia parcial de inicio con (filas en df2.B que comienzan con df1.A en el ejemplo a continuación y los valores de estas columnas son cadenas, que podrían ser de cualquier longitud).

Puedo hacerlo de la siguiente manera, pero es muy lento en mis marcos de datos reales, que tienen millones de filas cada uno.

df1 = pd.DataFrame({'A': ['a', 'b', 'cc']})

df2 = pd.DataFrame({'B': ['ar', 'd', 'ar'],
                    'C': ['x1', 'x1', 'x2']})

df_m = pd.DataFrame(columns=['A','B','C'])
for index, row in df1.iterrows():
    df_ = df2[df2['B'].str.startswith(row['A'])]
    if not df_.empty:
        df_['A'] = row['A']
        df_m = df_m.append(df_)

Df_m:

    A   B   C
0   a   ar  x1
2   a   ar  x2
2
Reveille 24 jun. 2020 a las 20:27

4 respuestas

La mejor respuesta

Use, Series.str.extract para extraer el key de la columna B en df2 que comienza con la columna A en df1, luego use DataFrame.merge para fusionar el marco de datos df1 en column A y {{ X7}} en la columna key:

key = df2['B'].str.extract('^(' + '|'.join(df1['A']) + ')')
df3 = df1.merge(df2.assign(key=key), left_on='A', right_on='key').drop('key', 1)

Resultado:

df3
   A   B   C
0  a  ar  x1
1  a  ar  x2
3
Shubham Sharma 24 jun. 2020 a las 17:55

Pruebe cartesian_product_basic con un filtro:

df3 = cartesian_product_basic(df1, df2)
df3[[a in b for a, b in zip(df3['A'], df3['B'])]]

   A   B   C
0  a  ar  x1
2  a  ar  x2

Si necesita productos cartesianos más rápidos, consulte ese enlace.

0
cs95 24 jun. 2020 a las 17:59

Si desea utilizar df.merge, puedes hacer esto:

df2[['l1','l2']] = pd.DataFrame(df2.B.apply(list).tolist(),index= df2.index)     
df_m = df1.merge(df2, left_on='A', right_on='l1').drop(['l1', 'l2'], 1)

Salida:

In [70]: df_m 
Out[70]: 
   A   B   C
0  a  ar  x1
1  a  ar  x2
3
Mayank Porwal 24 jun. 2020 a las 17:56

Nosotras podemos hacer findall con regex

reg='^('+'|'.join(df1.A.tolist())+')'
df2['A']=df2.B.str.findall(reg).str[0]
df2
Out[60]: 
    B   C  A
0  ar  x1  a
1  ba  x1  b
2  ar  x2  a
2
BEN_YO 24 jun. 2020 a las 17:35