2016-06-19 33 views
6

Dire che ho il seguente dataframe e voglio modificare i due elementi nella colonna c corrispondenti ai primi due elementi nella colonna uguali a 1 equivalenti a 2.Utilizzare loc e iloc insieme in panda

>>> df = pd.DataFrame({"a" : [1,1,1,1,2,2,2,2], "b" : [2,3,1,4,5,6,7,2], "c" : [1,2,3,4,5,6,7,8]}) 
>>> df.loc[df["a"] == 1, "c"].iloc[0:2] = 2 
>>> df 
    a b c 
0 1 2 1 
1 1 3 2 
2 1 1 3 
3 1 4 4 
4 2 5 5 
5 2 6 6 
6 2 7 7 
7 2 2 8 

Il codice nella seconda riga non funziona perché iLOC imposta una copia, così il dataframe originale non viene modificata. Come lo farei?

risposta

2

È possibile utilizzare Index.isin:

import pandas as pd 

df = pd.DataFrame({"a" : [1,1,1,1,2,2,2,2], 
        "b" : [2,3,1,4,5,6,7,2], 
        "c" : [1,2,3,4,5,6,7,8]}) 

#more general index      
df.index = df.index + 10 
print (df) 
    a b c 
10 1 2 1 
11 1 3 2 
12 1 1 3 
13 1 4 4 
14 2 5 5 
15 2 6 6 
16 2 7 7 
17 2 2 8 

print (df.index.isin(df.index[:2])) 
[ True True False False False False False False] 

df.loc[(df["a"] == 1) & (df.index.isin(df.index[:2])), "c"] = 2 
print (df) 
    a b c 
10 1 2 2 
11 1 3 2 
12 1 1 3 
13 1 4 4 
14 2 5 5 
15 2 6 6 
16 2 7 7 
17 2 2 8 

Se index è nice (parte da 0 senza duplicati):

df.loc[(df["a"] == 1) & (df.index < 2), "c"] = 2 
print (df) 
    a b c 
0 1 2 2 
1 1 3 2 
2 1 1 3 
3 1 4 4 
4 2 5 5 
5 2 6 6 
6 2 7 7 
7 2 2 8 

Un'altra soluzione:

mask = df["a"] == 1 
mask = mask & (mask.cumsum() < 3) 

df.loc[mask.index[:2], "c"] = 2 
print (df) 
    a b c 
0 1 2 2 
1 1 3 2 
2 1 1 3 
3 1 4 4 
4 2 5 5 
5 2 6 6 
6 2 7 7 
7 2 2 8 
4

Un modo sporco sarebbe :

df.loc[df[df['a']==1][:2].index, 'c'] = 2 
+1

Non penso che sia sporco! Questo è un esempio di una classe di slicing in cui è posizionale lungo un asse e per indice sull'altro. – piRSquared

+1

Sono stato in grado di salvare un carattere: 'df.loc [df.index [df.a == 1] [: 2], 'c'] = 2' – piRSquared

+0

@piRSquared In genere non mi piace la ripetizione in' df [df [col] == some_value] 'sintassi e qui diventa' df [df [df ['... Ecco perché l'ho chiamato sporco. :) – ayhan