web-dev-qa-db-fra.com

Manière correcte d'utiliser iloc dans les pandas

J'ai le dataframe suivant df:

print(df)

    Food         Taste
0   Apple        NaN
1   Banana       NaN
2   Candy        NaN
3   Milk         NaN
4   Bread        NaN
5   Strawberry   NaN

J'essaie de remplacer des valeurs dans une plage de lignes à l'aide d'iloc:

df.Taste.iloc[0:2] = 'good'
df.Taste.iloc[2:6] = 'bad'

Mais il a renvoyé le message SettingWithCopyWarning suivant:

SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame

Donc, j'ai trouvé ceci Stackoverflow page et essayé ceci:

df.iloc[0:2, 'Taste'] = 'good'
df.iloc[2:6, 'Taste'] = 'bad'

Malheureusement, l'erreur suivante a été renvoyée:

ValueError: Can only index by location with a [integer, integer slice (START point is INCLUDED, END point is EXCLUDED), listlike of integers, boolean array]

Quelle serait la bonne façon d'utiliser iloc dans cette situation? Aussi, y at-il un moyen de combiner ces deux lignes ci-dessus?

3
supernovaee

Vous pouvez utiliser Index.get_loc pour la position de la colonne Taste, car DataFrame.iloc select by positions:

#return second position (python counts from 0, so 1)
print (df.columns.get_loc('Taste'))
1

df.iloc[0:2, df.columns.get_loc('Taste')] = 'good'
df.iloc[2:6, df.columns.get_loc('Taste')] = 'bad'
print (df)
         Food Taste
0       Apple  good
1      Banana  good
2       Candy   bad
3        Milk   bad
4       Bread   bad
5  Strawberry   bad

La solution possible avec ix n'est pas recommandée car deprecate ix dans la prochaine version de pandas:

df.ix[0:2, 'Taste'] = 'good'
df.ix[2:6, 'Taste'] = 'bad'
print (df)
         Food Taste
0       Apple  good
1      Banana  good
2       Candy   bad
3        Milk   bad
4       Bread   bad
5  Strawberry   bad
6
jezrael

.iloc utilise l’emplacement entier, alors que .loc utilise le nom. Les deux options utilisent également les identificateurs de ligne ET colonne (pour les DataFrames). Votre code inital n'a pas fonctionné car vous n'avez pas spécifié dans l'appel .iloc la colonne que vous sélectionnez. La deuxième ligne de code que vous avez essayée n'a pas fonctionné car vous avez mélangé emplacement entier avec nom de colonne et .iloc n'accepte que l'emplacement entier. Si vous ne connaissez pas l'emplacement de la colonne, vous pouvez utiliser Index.get_loc à la place, comme suggéré ci-dessus. Sinon, utilisez la position entière, dans ce cas 1.

df.iloc[0:2, df.columns.get_loc('Taste')] = 'good'
df.iloc[2:6, df.columns.get_loc('Taste')] = 'bad'

est égal à:

df.iloc[0:2, 1] = 'good'
df.iloc[2:6, 1] = 'bad'

dans cette situation particulière.

6
Jared Stufft

Je préfère utiliser .loc dans de tels cas et utiliser explicitement l'index du DataFrame si vous souhaitez sélectionner la position:

df.loc[df.index[0:2], 'Taste'] = 'good'
df.loc[df.index[2:6], 'Taste'] = 'bad'
0
Rob

Indexation purement à l'emplacement entier pour la sélection par position. Exemple: -

lang_sets = {}
lang_sets['en'] = train[train.lang == 'en'].iloc[:,:-1]
lang_sets['ja'] = train[train.lang == 'ja'].iloc[:,:-1]
lang_sets['de'] = train[train.lang == 'de'].iloc[:,:-1]
0
HeadAndTail