Comment se débarrasser de la colonne «Sans nom: 0» dans un pandas DataFrame?

152

J'ai une situation dans laquelle parfois, lorsque je lis un csvde, dfj'obtiens une colonne indésirable semblable à un index nommé unnamed:0.

file.csv

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

Le CSV est lu avec ceci:

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

C'est très ennuyeux! Quelqu'un a-t-il une idée sur la façon de s'en débarrasser?

Michael Perdue
la source

Réponses:

186

C'est la colonne d'index, passez index=Falsepour ne pas l'écrire, voir la documentation

Exemple:

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

comparer avec:

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

Vous pouvez également indiquer read_csvque la première colonne est la colonne d'index en passant 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
la source
Souvent, les ensembles de données que vous obtenez d'ailleurs contiennent déjà cette colonne, donc cela n'aide pas vraiment à savoir comment produire le «bon» ensemble de données en utilisant les bons paramètres. Existe-t-il un moyen d'éliminer cette colonne lorsque vous la chargez alors qu'elle est déjà là?
Calvin Ku
2
@CalvinKu, malheureusement, il n'y a pas d' skipcolsargument pour read_csv, après avoir lu le csv, vous pouvez simplement le faire df = df.drop(columns=df.columns[0])ou vous pouvez simplement lire les colonnes en premier, puis passer les cols moins la première colonne quelque chose comme cols = pd.read_csv( ....., nrows=1).columns, puis relire à nouveau df = pd.read_csv(....., usecols=cols[1:])cela évite la surcharge de lecture une colonne superflue puis la laissant tomber par la suite
EdChum
43

Ce problème se manifeste probablement parce que votre CSV a été enregistré avec son RangeIndex(qui n'a généralement pas de nom). Le correctif devrait en fait être effectué lors de l'enregistrement du DataFrame, mais ce n'est pas toujours une option.

Éviter le problème: read_csvavec index_col argument

OMI, la solution la plus simple serait de lire la colonne sans nom comme index . Spécifiez un index_col=[0]argument à pd.read_csv, ceci lit dans la première colonne comme index.

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

Remarque
Vous auriez pu éviter cela en premier lieu en utilisant index=Falselors de la création du CSV de sortie, si votre DataFrame ne possède pas d'index pour commencer.

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

Mais comme mentionné ci-dessus, ce n'est pas toujours une option.


Solution Stopgap: Filtrer avec str.match

Si vous ne pouvez pas modifier le code pour lire / écrire le fichier CSV, vous pouvez simplement supprimer la colonne en filtrant avec 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
la source
1
Merci beaucoup! Ce index_col=[0]correctif a facilement résolu ce problème ennuyeux de «sans nom: 0» et évite au code de réinventer la roue.
user48115
1
Pour obtenir des colonnes sans nom, vous pouvez également utiliser des expressions régulières telles quedf.drop(df.filter(regex="Unname"),axis=1, inplace=True)
Sarah
8

Un autre cas où cela pourrait se produire est si vos données ont été mal écrites dans votre csvpour que chaque ligne se termine par une virgule. Cela vous laissera avec une colonne sans nom Unnamed: xà la fin de vos données lorsque vous essayez de les lire dans un fichier df.

Brendan
la source
2
J'avais l'habitude usecols=range(0,10)de couper la colonne sans nom
Nash
8

Pour obtenir toutes les colonnes sans nom, vous pouvez également utiliser des expressions régulières telles que df.drop(df.filter(regex="Unname"),axis=1, inplace=True)

Sarah
la source
2

Supprimez simplement cette colonne en utilisant: del df['column_name']

ssareen
la source