2015-06-02 10 views
7

Sono molto nuovo a Python, e mi chiedo che cosa la seguente riga di codice sta facendo e come potrebbe essere scritto in R:come convertire questa linea confuso di Python in R

df['sticky'] = df[['humidity', 'workingday']].apply(lambda x: (0, 1)[x['workingday'] == 1 and x['humidity'] >= 60], axis = 1) 

Ad esempio, qual è il significato di lambda x: (0, 1)?

P.S. df è un pandas dataframe

+6

Ragazzo che è un pezzo di codice illeggibile. –

+0

@MartijnPieters Considerando che ha spinto il lettore del codice a postare una domanda chiedendo cosa fa, direi che hai ragione :) – CoryKramer

+1

Non sai perché i downvotes, anche se un po 'più di contesto sarebbe utile. 'Df' a' dict' o numpy dataframe? – kdopen

risposta

5

Iniziamo dallo lambda. L'espressione completo è:

lambda x: (0, 1)[x['workingday'] == 1 and x['humidity'] >= 60] 

ed è una funzione anonima che prende un argomento x e ritorni:

  • 1 se x['workingday'] == 1 and x['humidity'] >= 60
  • 0 altrimenti

il (0, 1)[...] trucco è usato per restituire 0 o 1 invece di Python booleani False e True. Sfrutta il fatto che False e True saranno convertiti in numeri 0 e 1 se utilizzati al posto di un valore numerico, ad es. come indice di matrice (o tupla). Ad esempio, se l'espressione restituisce True, si accede alla cella 1 della tupla, che contiene 1.

Questa funzione è mappata su ogni riga della dataframe (Pandas?) (In realtà, solo su colonne filtrati 'humidity' e 'workingday') e il risultato viene memorizzato in 'sticky' colonna. Detto questo, è possibile tradurre la stessa espressione in R utilizzando un anonimo function e apply:

df$sticky <- apply(df[, c("workingday", "humidity")], 1, function(x) { 
    x["workingday"] == 1 & x["humidity"] >= 60; 
}); 

(il filtro non è probabilmente necessaria, ma le mie capacità di ricerca sono piuttosto arrugginito).

Tuttavia, c'è un modo più idiomatico di raggiungere lo stesso, come kdopen ha scritto:

df$sticky <- df$workingday == 1 & df$humidity >= 60 
+1

Avrei usato 'int (x ['workingday'] == 1 e x ['umidità']> = 60)' per convertire invece un valore booleano in un intero. –

+1

Ora per l'equivalente R :) – kdopen

+0

Asse = 1' significa per riga – hrbrmstr

0

devo dire che questo è strano modo per applicare una funzione a un df panda, in ogni caso questo è un esempio che mostra ciò che fa:

In [280]: 
# create the df 
df = pd.DataFrame({'a':np.arange(10), 'b':[1,1,1,2,2,3,3,4,5,5]}) 
df 

Out[280]: 
    a b 
0 0 1 
1 1 1 
2 2 1 
3 3 2 
4 4 2 
5 5 3 
6 6 3 
7 7 4 
8 8 5 
9 9 5 

l'espressione lambda sta chiamando apply e passando axis=1 che significa row-wise e testare ogni colonna denominata per se l'espressione è vera o falsa, la (0,1) getta l'accaduto a un int, altrimenti si otterrebbe un dtype booleano restituito.

In [285]: 

df.apply(lambda x: x['a'] > 5 and x['b'] < 5, axis=1) 
Out[285]: 
0 False 
1 False 
2 False 
3 False 
4 False 
5 False 
6  True 
7  True 
8 False 
9 False 
dtype: bool 

Con il (0,1) Cast:

In [282]: 
# apply a lambda, test if 'a' is greater and 5 and 'b' is less than 5, row-wise, cast the result to 1, 0 if True or False 
df.apply(lambda x: (0,1)[x['a'] > 5 and x['b'] < 5], axis=1) 
Out[282]: 
0 0 
1 0 
2 0 
3 0 
4 0 
5 0 
6 1 
7 1 
8 0 
9 0 
dtype: int64 

il modo in cui i panda sarebbe quello di fare in questo modo:

In [284]: 

((df['a'] > 5) & (df['b'] < 5)).astype(int) 
Out[284]: 
0 0 
1 0 
2 0 
3 0 
4 0 
5 0 
6 1 
7 1 
8 0 
9 0 
dtype: int32 

Non so R, quindi non posso commentare in merito

2

L'equivalente R idiomatico sarebbe

df$sticky <- df$workingday == 1 & df$humidity >= 60 

Supponendo che il desiderio sia ottenere una colonna di indicatori.

Stefano ha ben spiegato il codice Python. Una versione completamente espanso del lambda potrebbe essere

def func(x): 
    if x['workingday'] == 1 and x['humidity'] >= 60: 
     return 1 
    else: 
     return 0 

Ma si era mai scrivere che

0

A dplyr completo/soluzione riproducibile:

library(dplyr) 

set.seed(1492) 
df <- data_frame(working_day=sample(0:1, 100, replace=TRUE), 
       humidity=sample(20:90, 100, replace=TRUE)) 

df %>% mutate(sticky=working_day==1 & humidity >=60) -> df 

Se davvero necessità 0 o 1 :

df %>% mutate(sticky=as.numeric(working_day==1 & humidity >=60)) -> df 
Problemi correlati