2016-04-28 27 views
9

Say Ho il seguente dataframe:Modifica valori di riga dove certa condizione è soddisfatta in pandi

table

Qual è il modo più efficiente per aggiornare i valori delle colonne impresa e another_feat dove il flusso è il numero ?

È questo?

for index, row in df.iterrows(): 
    if df1.loc[index,'stream'] == 2: 
     # do something 

UPDATE: Cosa fare se ho più di un 100 colonne? Non voglio nominare esplicitamente le colonne che voglio aggiornare. Voglio dividere il valore di ogni colonna per 2 (eccetto per la colonna del flusso).

Quindi, per essere chiaro ciò che il mio obiettivo è:

Dividendo tutti i valori da 2 di tutte le righe che hanno flusso 2, ma non cambiare la colonna flusso

risposta

17

Penso che si possa utilizzare loc se necessario aggiornare due colonne per lo stesso valore:

df1.loc[df1['stream'] == 2, ['feat','another_feat']] = 'aaaa' 
print df1 
    stream  feat another_feat 
a  1 some_value some_value 
b  2  aaaa   aaaa 
c  2  aaaa   aaaa 
d  3 some_value some_value 

Se avete bisogno di aggiornamento separato, una possibilità è l'uso:

df1.loc[df1['stream'] == 2, 'feat'] = 10 
print df1 
    stream  feat another_feat 
a  1 some_value some_value 
b  2   10 some_value 
c  2   10 some_value 
d  3 some_value some_value 

Un'altra opzione comune è l'uso numpy.where:

df1['feat'] = np.where(df1['stream'] == 2, 10,20) 
print df1 
    stream feat another_feat 
a  1 20 some_value 
b  2 10 some_value 
c  2 10 some_value 
d  3 20 some_value 

EDIT: Se avete bisogno di dividere tutte le colonne senza stream cui condizione è True, uso:

print df1 
    stream feat another_feat 
a  1  4    5 
b  2  4    5 
c  2  2    9 
d  3  1    7 

#filter columns all without stream 
cols = [col for col in df1.columns if col != 'stream'] 
print cols 
['feat', 'another_feat'] 

df1.loc[df1['stream'] == 2, cols ] = df1/2 
print df1 
    stream feat another_feat 
a  1 4.0   5.0 
b  2 2.0   2.5 
c  2 1.0   4.5 
d  3 1.0   7.0 
+0

Ho aggiornato la mia domanda, ho più di 100 colonne, come potrei fare questo? – Stanko

+0

@Stanko - Penso che sia un'altra domanda: è necessario selezionare alcune colonne '100' in qualche modo. per esempio. se hai bisogno delle prime colonne '100', usa' df.columns [: 100] 'e poi passa a' loc'. – jezrael

+0

Non voglio necessariamente le prime 100 colonne, voglio solo dividere tutti i valori delle colonne (tranne la colonna del flusso) per 2 dove il flusso è f.e. 2 – Stanko

0

si può fare lo stesso con .ix , come questo:

In [1]: df = pd.DataFrame(np.random.randn(5,4), columns=list('abcd')) 

In [2]: df 
Out[2]: 
      a   b   c   d 
0 -0.323772 0.839542 0.173414 -1.341793 
1 -1.001287 0.676910 0.465536 0.229544 
2 0.963484 -0.905302 -0.435821 1.934512 
3 0.266113 -0.034305 -0.110272 -0.720599 
4 -0.522134 -0.913792 1.862832 0.314315 

In [3]: df.ix[df.a>0, ['b','c']] = 0 

In [4]: df 
Out[4]: 
      a   b   c   d 
0 -0.323772 0.839542 0.173414 -1.341793 
1 -1.001287 0.676910 0.465536 0.229544 
2 0.963484 0.000000 0.000000 1.934512 
3 0.266113 0.000000 0.000000 -0.720599 
4 -0.522134 -0.913792 1.862832 0.314315 

EDIT

Dopo che le informazioni supplementari, il seguente restituirà tutte le colonne - in cui è soddisfatta una certa condizione - con valori dimezzati:

>> condition = df.a > 0 
>> df[condition][[i for i in df.columns.values if i not in ['a']]].apply(lambda x: x/2) 

Spero che questo aiuta!

+0

Questo è fattibile se non ho molte colonne, dovrei dire che ho più di 100 colonne. – Stanko

+0

Ho testato l'ultima modifica con 'condition = (df.a == -1.001287)' aspettando che i valori da dividere della riga in cui 'a == -1.001287' ma ho recuperato un dataframe vuoto. – Stanko

+0

Sì, questo è perché questo è solo il display, non il valore reale, ottiene il valore reale in questo modo: 'df.iloc [1,0]'. O meglio ancora, imposta il valore tu stesso e poi riprova: 'df.iloc [1,0] = 1.2345; condition = df.a == 1.2345' – Thanos