Hola chicos necesito su ayuda.
Tengo df con dos columnas A y B, ambas son columnas con valores de cadena
ejemplo:
df_1 = pd.DataFrame(data={ "A":['a','b','c'], "B":['ax d','zy w','qm c'] #string values not a list }) print(df_1) #output AB 0 aaxd 1 bzyw 2 cqmcahora lo que estoy tratando de hacer es preformar loc en el df_1 para obtener toda la fila en la que la columna B contiene el valor de la cadena en la columna A.
En este ejemplo, la salida que quiero es la primera y la tercera fila.
AB 0 aaxd # 'axd' contain value 'a' 2 cqmc # 'qmc' contain value 'c'Probé diferentes condiciones de ubicación, pero obtuve un tipo que no se puede modificar: error 'Serie':
df_1.loc[df_1["B"].str.contains(df_1["A"])] #TypeError: unhashable type: 'Series' df_1.loc[df_1["A"] in df_1["B"]] #TypeError: unhashable type: 'Series'Realmente no quiero usar un bucle for/while debido al tamaño del df.
¿Alguna idea de cómo puedo preformar esto? Gracias
Puedes probar:
out = df_1.loc[df_1.apply(lambda x: x['A'] in x['B'], axis=1)] print(out) # Output AB 0 aaxd 2 cqmc Alternativa con numpy :
df_1.loc[np.apply_along_axis(lambda x: x[0] in x[1], axis=1, arr=df_1)]No existe un método vectorial, in mapear usando dos columnas. Necesitas hacer un bucle aquí:
mask = [a in b for a,b in zip(df_1['A'], df_1['B'])] df_1.loc[mask]Producción:
AB 0 aaxd 2 cqmc # operator.contains 518 µs ± 4.61 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) # list comprehension 554 µs ± 3.84 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) # numpy.apply_along_axis 7.32 ms ± 58.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) # apply 20.7 ms ± 379 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)¡Lindo!
from operator import contains df_1.loc[map(contains, *map(df_1.get, ['B', 'A']))] AB 0 aaxd 2 cqmcY sin el import pero con un feo dunder.../-:
df_1.loc[map(str.__contains__, *map(df_1.get, ['B', 'A']))]Además, al OP ... no acepte esta respuesta. Solo estaba jugando al golf. Nunca debe usar esto en el código de producción, ya que es menos que transparente debido al uso de 2 mapas y un símbolo.
Y para ser super duper claro...
Al acceder a dos columnas diferentes en pandas, puede usar .apply()
df.apply(lambda row: row['A'] in row['B'], axis = 1)Esto crea una serie booleana que puede usar para su condición de ubicación que selecciona solo las columnas donde 'A' está en 'B':
df.loc[df.apply(lambda row: row['A'] in row['B'], axis = 1)]df_1[df_1.apply(lambda x:x['A'] in x['B'],axis=1)]