es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Agrupa y devuelve todos los valores de índice donde existe una subcadena de texto en una columna.

Tengo un df con la siguiente estructura:

   vid  sid   pid      url 
1   A    A1   page     ABCDEF   
2   A    A1   page     DEF123
3   A    A1   page     GHI345
4   A    A1   page     JKL345
5   B    B1   page     AB12345EF
6   B    B2   page     IJK
7   B    B2   page     XYZ
8   C    C1   page     ABCEF

dict = {'vid':{1:'A',2:'A',3:'A',4:'A',5:'B',6:'B',7:'B',8:'C'},
        'sid':{1:'A1',2:'A1',3:'A1',4:'A1',5:'B1',6:'B2',7:'B2&##39;,8:'C1'},
        'page':{1:'page',2:'page',3:'page',4:'page',5:'page',6:'page',7:'page',8:'pge'},
        'url':{1:'ABC',2:'DEF',3:'GHI',4:'JKL',5:'ABC',6:'IJK',7:'XYZ',8:'ABC'}
}

También tengo una lista de subcadenas:

lst = ['AB','EF']

Básicamente, quiero agrupar por sid y verificar cada fila en url. Si todos los elementos de la lista existen como subcadena en al menos una fila, entonces devolver el sid. Si no, filtrar el sid del df. Las subcadenas dentro de url no son secuenciales.

Pseudocódigo:

agrupar por sid
si la fila en url contiene todas las subcadenas en lst
       pasar
si ninguna fila en url contiene todas las subcadenas en lst
       eliminar el `sid` del df

Resultado de aplicar la lógica anterior al df usando lst:

enter code here

      vid  sid   pid      url 
1   A    A1   page     ABCDEF   
2   A    A1   page     DEF123
3   A    A1   page     GHI345
4   A    A1   page     JKL345
5   B    B1   page     AB12345EF
8   C    C1   page     ABCEF
Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Para obtener el resultado deseado, podemos usar una combinación de los métodos groupby(), apply() y str.contains() de Pandas. Aquí está el código:

    import pandas as pd
    
    # crear el dataframe y el diccionario
    df = pd.DataFrame({'vid': ['A', 'A', 'A', 'A', 'B', 'B', 'B', 'C'],
                       'sid': ['A1', 'A1', 'A1', 'A1', 'B1', 'B2', 'B2', 'C1'],
                       'pid': ['page', 'page', 'page', 'page', 'page', 'page', 'page', 'page'],
                       'url': ['ABCDEF', 'DEF123', 'GHI345', 'JKL345', 'AB12345EF', 'IJK', 'XYZ', 'ABCEF']})
    
    dict = {'vid': {1: 'A', 2: 'A', 3: 'A', 4: 'A', 5: 'B', 6: 'B', 7: 'B', 8: 'C'},
            'sid': {1: 'A1', 2: 'A1', 3: 'A1', 4: 'A1', 5: 'B1', 6: 'B2', 7: 'B2', 8: 'C1'},
            'page': {1: 'page', 2: 'page', 3: 'page', 4: 'page', 5: 'page', 6: 'page', 7: 'page', 8: 'pge'},
            'url': {1: 'ABC', 2: 'DEF', 3: 'GHI', 4: 'JKL', 5: 'ABC', 6: 'IJK', 7: 'XYZ', 8: 'ABC'}}
    
    # convertir el diccionario a un dataframe con el índice correcto
    dict_df = pd.DataFrame(dict).rename_axis(index='id')
    
    # fusionar los dos dataframes por índice
    merged_df = pd.merge(df, dict_df, left_index=True, right_index=True)
    
    # definir la lista de subcadenas
    lst = ['AB', 'EF']
    
    # crear una función para comprobar si todas las subcadenas están en una fila de urls
    def check_substr(row):
        return all(sub in row['url'] for sub in lst)
    
    # agrupar por sid y aplicar la función a cada grupo
    grouped = merged_df.groupby('sid').apply(lambda x: x[check_substr(x)])
    
    # filtrar los sids que no tienen todas las subcadenas en al menos una fila
    filtered_sids = grouped[grouped['sid'].duplicated(keep=False)]['sid'].unique()
    
    # filtrar el dataframe original por los sids que pasan la comprobación
    result = df[df['sid'].isin(filtered_sids)]
    

    Aquí hay un desglose paso a paso de lo que hace el código:

    1. Crear el dataframe original (df) y el diccionario (dict) con la estructura dada.
    2. Convertir el diccionario en un dataframe separado con el índice correcto (dict_df).
    3. Fusionar los dos dataframes (df y dict_df) por índice para obtener una tabla completa.
    4. Definir la lista de subcadenas (lst).
    5. Crear una función (check_substr) que comprueba si todas las subcadenas en lst existen en una fila de url.
    6. Agrupar el dataframe fusionado por sid, luego aplicar la función check_substr a cada grupo usando apply().
    7. Filtrar los sids que no tienen todas las subcadenas en al menos una fila usando los métodos duplicated() y unique().
    8. Filtrar el dataframe original (df) por los sids filtrados para obtener el resultado deseado.

    El dataframe resultante (result) debería ser:

      vid sid   pid        url
    0   A  A1  page     ABCDEF
    1   A  A1  page     DEF123
    2   A  A1  page     GHI345
    3   A  A1  page     JKL345
    4   B  B1  page  AB12345EF
    7   C  C1  page      ABCEF
    

Comments are closed.