¿Cuál es la forma más sencilla de eliminar columnas duplicadas de un marco de datos?
Estoy leyendo un archivo de texto que tiene columnas duplicadas a través de:
import pandas as pd
df=pd.read_table(fname)
Los nombres de las columnas son:
Time, Time Relative, N2, Time, Time Relative, H2, etc...
Todas las columnas Tiempo y Relativo al tiempo contienen los mismos datos. Quiero:
Time, Time Relative, N2, H2
Todos mis intentos de eliminar, eliminar, etc., como:
df=df.T.drop_duplicates().T
Da como resultado errores de índice con valor único:
Reindexing only valid with uniquely valued index objects
Perdón por ser un novato de Pandas. Cualquier sugerencia sera apreciada.
Detalles adicionales
Versión de Pandas: 0.9.0
Versión de Python: 2.7.3
Windows 7
(instalado a través de Pythonxy 2.7.3.0)
archivo de datos (nota: en el archivo real, las columnas están separadas por pestañas, aquí están separadas por 4 espacios):
Time Time Relative [s] N2[%] Time Time Relative [s] H2[ppm]
2/12/2013 9:20:55 AM 6.177 9.99268e+001 2/12/2013 9:20:55 AM 6.177 3.216293e-005
2/12/2013 9:21:06 AM 17.689 9.99296e+001 2/12/2013 9:21:06 AM 17.689 3.841667e-005
2/12/2013 9:21:18 AM 29.186 9.992954e+001 2/12/2013 9:21:18 AM 29.186 3.880365e-005
... etc ...
2/12/2013 2:12:44 PM 17515.269 9.991756+001 2/12/2013 2:12:44 PM 17515.269 2.800279e-005
2/12/2013 2:12:55 PM 17526.769 9.991754e+001 2/12/2013 2:12:55 PM 17526.769 2.880386e-005
2/12/2013 2:13:07 PM 17538.273 9.991797e+001 2/12/2013 2:13:07 PM 17538.273 3.131447e-005
import pandas as pd; pd.__version__
)read_table
el ejemplo que inventé.Respuestas:
Hay una solución de una línea al problema. Esto se aplica si algunos nombres de columna están duplicados y desea eliminarlos:
Cómo funciona:
Suponga que las columnas del marco de datos son
['alpha','beta','alpha']
df.columns.duplicated()
devuelve una matriz booleana: unaTrue
oFalse
de cada columna. Si esFalse
así, el nombre de la columna es único hasta ese momento; si lo esTrue
, el nombre de la columna se ha duplicado anteriormente. Por ejemplo, usando el ejemplo dado, el valor devuelto sería[False,False,True]
.Pandas
permite indexar usando valores booleanos por lo que selecciona solo losTrue
valores. Como queremos mantener las columnas sin duplicar, necesitamos que la matriz booleana anterior se invierta (es decir[True, True, False] = ~[False,False,True]
)Finalmente,
df.loc[:,[True,True,False]]
selecciona solo las columnas no duplicadas usando la capacidad de indexación antes mencionada.Nota : lo anterior solo verifica los nombres de las columnas, no los valores de las columnas.
fuente
df.T.drop_duplicates().T
.Parece que ya conoce los nombres únicos de las columnas. Si ese es el caso, entonces
df = df['Time', 'Time Relative', 'N2']
funcionaría.Si no es así, su solución debería funcionar:
Probablemente tenga algo específico en sus datos que lo arruine. Podríamos brindarle más ayuda si hay más detalles que pueda brindarnos sobre los datos.
Editar: Como dijo Andy, el problema probablemente esté en los títulos de columna duplicados.
Para un archivo de tabla de muestra 'dummy.csv' que inventé:
el uso
read_table
da columnas únicas y funciona correctamente:Si su versión no lo permite, puede crear una solución para que sean únicos:
fuente
df['Time']
selecciona todas las series de tiempo (es decir, devuelve un DataFrame), ydf['Time', ..]
esto devolverá el DataFrame completo.RecursionError: maximum recursion depth exceeded
La transposición es ineficaz para DataFrames grandes. Aquí hay una alternativa:
Úselo así:
Editar
Una versión de memoria eficiente que trata nans como cualquier otro valor:
fuente
my_df.T.drop_duplicates().T
colgaría de grandes marcos de datos./usr/local/lib/python3.5/dist-packages/ipykernel_launcher.py:17: DeprecationWarning: 'pandas.core.common.array_equivalent' is deprecated and is no longer public API
if array_equivalent(ia, ja):
conif np.array_equal(ia, ja):
parece producir los mismos resultados, pero leí que no maneja bien los NaN.array_equivalent
todavía está disponible en el repositorio público, posiblemente en una rama más antigua?numpy.array_equiv
; para pandas, no veo ninguna rama de lanzamiento anterior en GitHub,pandas.core.common
pero tal vez haya otros lugares para buscarSi no me equivoco, lo siguiente hace lo que se pidió sin los problemas de memoria de la solución de transposición y con menos líneas que la función de @kalu, manteniendo la primera de las columnas con nombres similares.
fuente
Parece que estaba en el camino correcto. Aquí está el resumen que estaba buscando:
Pero como no hay un marco de datos de ejemplo que produzca el mensaje de error al que se hace referencia
Reindexing only valid with uniquely valued index objects
, es difícil decir exactamente qué resolvería el problema. si restaurar el índice original es importante para usted, haga esto:fuente
Primer paso: - Leer la primera fila, es decir, todas las columnas, eliminar todas las columnas duplicadas.
Segundo paso: - Finalmente leer solo esas columnas.
fuente
Me encontré con este problema en el que la línea proporcionada por la primera respuesta funcionó bien. Sin embargo, tuve la complicación adicional de que la segunda copia de la columna tenía todos los datos. La primera copia no lo hizo.
La solución fue crear dos marcos de datos dividiendo el único marco de datos alternando el operador de negación. Una vez que tuve los dos marcos de datos, ejecuté una declaración de combinación usando
lsuffix
. De esta manera, podría hacer referencia y eliminar la columna sin los datos.- E
fuente
La forma a continuación identificará columnas duplicadas para revisar qué está fallando al construir el marco de datos originalmente.
fuente
Manera rápida y fácil de eliminar las columnas duplicadas por sus valores:
df = df.T.drop_duplicates (). T
Más información: Pandas DataFrame drop_duplicates manual .
fuente