¿Cómo deshacerse de la columna "Sin nombre: 0" en un DataFrame de pandas?

152

Tengo una situación en la que a veces, cuando leo una csvde dfobtengo un índice similar columna llamada no deseada unnamed:0.

file.csv

,A,B,C
0,1,2,3
1,4,5,6
2,7,8,9

El CSV se lee con esto:

pd.read_csv('file.csv')

   Unnamed: 0  A  B  C
0           0  1  2  3
1           1  4  5  6
2           2  7  8  9

Esto es muy molesto! ¿Alguien tiene una idea sobre cómo deshacerse de esto?

Michael Perdue
fuente

Respuestas:

186

Es la columna de índice, pasa index=Falsepara no escribirla, mira los documentos

Ejemplo:

In [37]:
df = pd.DataFrame(np.random.randn(5,3), columns=list('abc'))
pd.read_csv(io.StringIO(df.to_csv()))

Out[37]:
   Unnamed: 0         a         b         c
0           0  0.109066 -1.112704 -0.545209
1           1  0.447114  1.525341  0.317252
2           2  0.507495  0.137863  0.886283
3           3  1.452867  1.888363  1.168101
4           4  0.901371 -0.704805  0.088335

Comparar con:

In [38]:
pd.read_csv(io.StringIO(df.to_csv(index=False)))

Out[38]:
          a         b         c
0  0.109066 -1.112704 -0.545209
1  0.447114  1.525341  0.317252
2  0.507495  0.137863  0.886283
3  1.452867  1.888363  1.168101
4  0.901371 -0.704805  0.088335

Opcionalmente, también puede decir read_csvque la primera columna es la columna de índice pasando index_col=0:

In [40]:
pd.read_csv(io.StringIO(df.to_csv()), index_col=0)

Out[40]:
          a         b         c
0  0.109066 -1.112704 -0.545209
1  0.447114  1.525341  0.317252
2  0.507495  0.137863  0.886283
3  1.452867  1.888363  1.168101
4  0.901371 -0.704805  0.088335
EdChum
fuente
Muchas veces los conjuntos de datos que obtiene de otros lugares ya contienen esta columna, por lo que realmente no ayuda saber cómo producir el conjunto de datos "correcto" utilizando los parámetros correctos. ¿Hay alguna forma de eliminar esta columna cuando la carga cuando ya está allí?
Calvin Ku
2
@CalvinKu desafortunadamente no hay skipcolsargumento para read_csv, después de leer en el csv que simplemente puede hacer df = df.drop(columns=df.columns[0])o simplemente puede leer las columnas primero y luego pasar los cols menos la primera columna algo así cols = pd.read_csv( ....., nrows=1).columnsy luego volver a leer de nuevo df = pd.read_csv(....., usecols=cols[1:])esto evita la sobrecarga de la lectura una columna superflua y luego dejarla caer
EdChum
43

Es probable que este problema se manifieste porque su CSV se guardó junto con su RangeIndex(que generalmente no tiene un nombre). La solución realmente debería hacerse al guardar el DataFrame, pero esto no siempre es una opción.

Evitando el problema: read_csvcon index_col argumento

En mi opinión, la solución más simple sería leer la columna sin nombre como índice . Especifique un index_col=[0]argumento para pd.read_csv, esto se lee en la primera columna como índice.

df = pd.DataFrame('x', index=range(5), columns=list('abc'))
df

   a  b  c
0  x  x  x
1  x  x  x
2  x  x  x
3  x  x  x
4  x  x  x

# Save DataFrame to CSV.
df.to_csv('file.csv')

pd.read_csv('file.csv')

   Unnamed: 0  a  b  c
0           0  x  x  x
1           1  x  x  x
2           2  x  x  x
3           3  x  x  x
4           4  x  x  x

# Now try this again, with the extra argument.
pd.read_csv('file.csv', index_col=[0])

   a  b  c
0  x  x  x
1  x  x  x
2  x  x  x
3  x  x  x
4  x  x  x

Nota:
En primer lugar, podría haber evitado esto al usar index=Falseel CSV de salida, si su DataFrame no tiene un índice para empezar.

df.to_csv('file.csv', index=False)

Pero como se mencionó anteriormente, esto no siempre es una opción.


Solución provisional: filtrado con str.match

Si no puede modificar el código para leer / escribir el archivo CSV, puede eliminar la columna filtrándola con str.match:

df 

   Unnamed: 0  a  b  c
0           0  x  x  x
1           1  x  x  x
2           2  x  x  x
3           3  x  x  x
4           4  x  x  x

df.columns
# Index(['Unnamed: 0', 'a', 'b', 'c'], dtype='object')

df.columns.str.match('Unnamed')
# array([ True, False, False, False])

df.loc[:, ~df.columns.str.match('Unnamed')]

   a  b  c
0  x  x  x
1  x  x  x
2  x  x  x
3  x  x  x
4  x  x  x
cs95
fuente
1
¡Muchas gracias! Esa index_col=[0]solución resolvió fácilmente este molesto problema de 'sin nombre: 0' y ahorra código de reinventar detalladamente la rueda.
user48115
1
Para obtener el paseo de columnas sin nombre, también puede usar expresiones regulares comodf.drop(df.filter(regex="Unname"),axis=1, inplace=True)
Sarah
8

Otro caso en el que esto podría estar sucediendo es si sus datos se escribieron incorrectamente csvpara que cada fila termine con una coma. Esto lo dejará con una columna sin nombre Unnamed: xal final de sus datos cuando intente leerlos en un df.

Brendan
fuente
2
Solía usecols=range(0,10)cortar la columna sin nombre
Nash, el
8

Para obtener acceso a todas las columnas sin nombre, también puede usar expresiones regulares como df.drop(df.filter(regex="Unname"),axis=1, inplace=True)

Sarah
fuente
2

Simplemente elimine esa columna usando: del df['column_name']

ssareen
fuente