Tengo un marco de datos que contiene múltiples datos en una columna

    ID                                            classes
4   5792.0  Mechanics (any of the two sessions), Analysis ...
6   5915.0  Mechanics (any of the two sessions), Perspecti...
8   5931.0                        CS, Chemistry, Perspecti...
9   5991.0                                    Perspective, CS
10  5841.0  Mechanics (any of the two sessions), Perspecti...

La columna "clases" puede tener valores como "Perspectiva, Química, CS", etc. Quiero ordenar el marco de datos anterior en función de los valores en la cadena de clases

Por ejemplo, una salida podría ser

        ID  classes                                         
4   5792.0       CS
6   5915.0       CS
8   5931.0       CS
9   5991.0       CS                            
10  5841.0       CS

Así ordenado según las clases a las que asistió,

Busqué en google, pero todos los resultados estaban ordenando el marco de datos en función del valor único (valor único por celda)

Gracias de antemano

1
Allaw Hussein 10 may. 2020 a las 00:16

3 respuestas

La mejor respuesta

Datos

df=pd.DataFrame({'ID':[5792.0,5915.0,5931.0,5991.0,5841.0 ],'classes':['Mechanics (any of the two sessions), Perspecti,CS, Chemistry','Mechanics (any of the two sessions), Perspecti,CS, Chemistry','Mechanics (any of the two sessions), Perspecti,CS, Chemistry','Mechanics (any of the two sessions), Perspecti,CS, Chemistry','Mechanics (any of the two sessions), Perspecti,CS, Chemistry']})
df

Use df.str.split para convertir cadenas en classes para listar

df['classes']=df.classes.str.split(",")

Explotar y ordenar por classes

df.explode('classes').sort_values(by='classes')

Salir

enter image description here

1
wwnde 9 may. 2020 a las 21:49

Supongo que desea ordenar cada cadena en la columna de clases dividida por comas, puede intentar esto:

df['string'] = df['classes'].apply(lambda x: ' '.join(sorted(x.split(', '))))
print(df)
0
NYC Coder 9 may. 2020 a las 21:26

Estoy seguro de que hay una forma más "pandas" de hacer esto, pero aquí hay una posible solución:

cs_df = df[df['classes'].apply(lambda x: 'CS' in x)]
cs_df['classes'] = 'CS'

En el ejemplo anterior, cs_df debe contener todas las filas del marco de datos original donde 'CS' está en classes. Puede hacerlo manualmente o en un bucle para obtener todos sus marcos de datos.

Explicación:

Cuando usamos df['classes'], pandas devuelve una instancia numpy.Series. numpy.Series.apply toma una función como argumento y la aplica a cada elemento de la serie. Por ejemplo:

# square each item in the series
s1 = numpy.Series([1,2,3]).apply(lambda x: x*x)
#[1,4,9]
# root each item in the series
s2 = s1.apply(sqrt)
#[1,2,3]

Pandas también tiene una lógica de indexación especial. Si utiliza un Series de bool s como índice en un Dataframe, los pandas devolverán un Dataframe donde los elementos en la serie de índice fueron True.

Entonces en este ejemplo

s = numpy.Series([True, False, True])
df2 = df[s]

df2 solo contendrá las filas 0 y 2 del original df.

Finalmente, los pandas también tienen una lógica especial para la asignación por índice. Puede establecer columnas enteras en un solo valor escalar sin necesidad de un ciclo de explit:

df['best_column'] = "best value"

En el ejemplo anterior, el marco de datos tendrá una nueva columna llena de valores "best value".

0
DragonBobZ 9 may. 2020 a las 22:18