Convertir la ligne en en-tête de colonne pour Pandas DataFrame,
111
Les données avec lesquelles je dois travailler sont un peu désordonnées. Il a des noms d'en-tête à l'intérieur de ses données. Comment puis-je choisir une ligne dans un dataframe pandas existant et en faire (la renommer en) un en-tête de colonne?
In[21]: df = pd.DataFrame([(1,2,3),('foo','bar','baz'),(4,5,6)])In[22]: dfOut[22]:01201231 foo bar baz2456
Définissez les étiquettes de colonne pour qu'elles correspondent aux valeurs de la deuxième ligne (emplacement d'index 1):
In[23]: df.columns = df.iloc[1]
Si l'index a des libellés uniques, vous pouvez supprimer la deuxième ligne en utilisant:
In[24]: df.drop(df.index[1])Out[24]:1 foo bar baz01232456
Si l'index n'est pas unique, vous pouvez utiliser:
In[133]: df.iloc[pd.RangeIndex(len(df)).drop(1)]Out[133]:1 foo bar baz01232456
L'utilisation df.drop(df.index[1])supprime toutes les lignes avec le même libellé que la deuxième ligne. Parce que les index non uniques peuvent conduire à des pierres d'achoppement (ou des bogues potentiels) comme celui-ci, il est souvent préférable de veiller à ce que l'index soit unique (même si Pandas n'en a pas besoin).
Merci beaucoup pour votre réponse rapide! Comment puis-je choisir une ligne par valeur au lieu de l'emplacement de l'index pour en faire un en-tête? Donc, pour votre exemple, quelque chose comme .. df.columns = df [df [0] == 'foo']
EK
Le problème avec cela est qu'il pourrait y avoir plus d'une ligne qui a la valeur "foo". Une façon de contourner ce problème est de choisir explicitement la première telle ligne: df.columns = df.iloc[np.where(df[0] == 'foo')[0][0]].
unutbu
Ah je vois pourquoi tu as fait ça. Pour mon cas, je sais qu'il n'y a qu'une seule ligne qui a la valeur "foo". Alors ça va. Je viens de faire de cette façon, je suppose que c'est le même que celui que vous m'avez donné ci-dessus. idx_loc = df [df [0] == 'toto']. index.tolist () [0] df.columns = df.iloc [idx_loc]
"foo"
. Une façon de contourner ce problème est de choisir explicitement la première telle ligne:df.columns = df.iloc[np.where(df[0] == 'foo')[0][0]]
.Cela fonctionne (pandas v'0.19.2 '):
la source
.drop(df.index[0])
Il serait plus facile de recréer la trame de données. Cela interpréterait également les types de colonnes à partir de zéro.
la source
Vous pouvez spécifier l'index de ligne dans les constructeurs read_csv ou read_html via le
header
paramètre qui représenteRow number(s) to use as the column names, and the start of the data
. Cela a l'avantage de supprimer automatiquement toutes les lignes précédentes qui sont supposées être indésirables.la source