unir datos dataframes concatenar combinar columnas agrupar python pandas

datos - unir dos columnas en python



Devuelve mĂșltiples columnas desde aplicar pandas (4)

Algunas de las respuestas actuales funcionan bien, pero quiero ofrecer otra opción, tal vez más "pandificada". Esto me funciona con los pandas actuales 0.22 (no estoy seguro si funcionará en versiones anteriores):

import pandas as pd df_test = pd.DataFrame([ {''dir'': ''/Users/uname1'', ''size'': 994933}, {''dir'': ''/Users/uname2'', ''size'': 109338711}, ]) def sizes(s): a = locale.format("%.1f", s[''size''] / 1024.0, grouping=True) + '' KB'' b = locale.format("%.1f", s[''size''] / 1024.0 ** 2, grouping=True) + '' MB'' c = locale.format("%.1f", s[''size''] / 1024.0 ** 3, grouping=True) + '' GB'' return a, b, c df_test[[''size_kb'', ''size_mb'', ''size_gb'']] = df_test.apply(sizes, axis=1, result_type="expand")

Tenga en cuenta que el truco está en el parámetro tipo de resultado de DataFrame , que expandirá su resultado en un DataFrame que se puede asignar directamente a columnas nuevas / antiguas.

Tengo un marco de datos de pandas, df_test . Contiene una columna ''tamaño'' que representa el tamaño en bytes. He calculado KB, MB y GB utilizando el siguiente código:

df_test = pd.DataFrame([ {''dir'': ''/Users/uname1'', ''size'': 994933}, {''dir'': ''/Users/uname2'', ''size'': 109338711}, ]) df_test[''size_kb''] = df_test[''size''].astype(int).apply(lambda x: locale.format("%.1f", x / 1024.0, grouping=True) + '' KB'') df_test[''size_mb''] = df_test[''size''].astype(int).apply(lambda x: locale.format("%.1f", x / 1024.0 ** 2, grouping=True) + '' MB'') df_test[''size_gb''] = df_test[''size''].astype(int).apply(lambda x: locale.format("%.1f", x / 1024.0 ** 3, grouping=True) + '' GB'') df_test dir size size_kb size_mb size_gb 0 /Users/uname1 994933 971.6 KB 0.9 MB 0.0 GB 1 /Users/uname2 109338711 106,776.1 KB 104.3 MB 0.1 GB [2 rows x 5 columns]

He ejecutado esto en más de 120,000 filas y el tiempo toma alrededor de 2.97 segundos por columna * 3 = ~ 9 segundos según% timeit.

¿Hay alguna manera puedo hacer esto más rápido? Por ejemplo, ¿puedo en lugar de devolver una columna a la vez de aplicar y ejecutar 3 veces, puedo devolver las tres columnas en una pasada para volver a insertarlas en el marco de datos original?

Las otras preguntas que encontré todas quieren tomar múltiples valores y devolver un solo valor. Quiero tomar un solo valor y devolver varias columnas.


Esta es una pregunta antigua, pero para completar, puede devolver una Serie de la función aplicada que contiene los nuevos datos, evitando la necesidad de iterar tres veces. Pasar axis=1 a la función de aplicación aplica los sizes función a cada fila del marco de datos, devolviendo una serie para agregar a un nuevo marco de datos. Esta serie, s, contiene los nuevos valores, así como los datos originales.

def sizes(s): s[''size_kb''] = locale.format("%.1f", s[''size''] / 1024.0, grouping=True) + '' KB'' s[''size_mb''] = locale.format("%.1f", s[''size''] / 1024.0 ** 2, grouping=True) + '' MB'' s[''size_gb''] = locale.format("%.1f", s[''size''] / 1024.0 ** 3, grouping=True) + '' GB'' return s df_test = df_test.append(rows_list) df_test = df_test.apply(sizes, axis=1)


Generalmente, para devolver múltiples valores, esto es lo que hago.

def gimmeMultiple(group): x1 = 1 x2 = 2 return array([[1, 2]]) def gimmeMultipleDf(group): x1 = 1 x2 = 2 return pd.DataFrame(array([[1,2]]), columns=[''x1'', ''x2'']) df[''size''].astype(int).apply(gimmeMultiple) df[''size''].astype(int).apply(gimmeMultipleDf)

Devolver un marco de datos definitivamente tiene sus ventajas, pero a veces no es necesario. Puedes ver lo que devuelve el apply() y jugar un poco con las funciones;)


Use aplicar y zip será 3 veces más rápido que en serie.

def sizes(s): return locale.format("%.1f", s / 1024.0, grouping=True) + '' KB'', / locale.format("%.1f", s / 1024.0 ** 2, grouping=True) + '' MB'', / locale.format("%.1f", s / 1024.0 ** 3, grouping=True) + '' GB'' df_test[''size_kb''], df_test[''size_mb''], df_test[''size_gb''] = zip(*df_test[''size''].apply(sizes))

Resultado de la prueba son:

Separate df.apply(): 100 loops, best of 3: 1.43 ms per loop Return Series: 100 loops, best of 3: 2.61 ms per loop Return tuple: 1000 loops, best of 3: 819 µs per loop