2015-06-02 29 views
7

我很新的Python和我不知道下面的代码行是干什么和怎么会写在R:如何到Python的这种混乱线转换成R

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

例如, lambda x: (0, 1)是什么意思?

P.S. dfpandas数据帧

+6

男孩,是一块不可读的代码。 –

+0

@MartijnPieters考虑到它提示读者的代码发布一个问题,询问它是什么,我会说你是对的:) – CoryKramer

+1

不知道为什么downvotes,虽然多一点上下文会有用。 'df'是一个'dict'还是一个numpy数据框? – kdopen

回答

5

我们从lambda开始。将完整的表达是:

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

,它是一个匿名函数,有一个参数x和回报:

  • 1如果x['workingday'] == 1 and x['humidity'] >= 60
  • 0否则

(0, 1)[...]诀窍是使用返回01而不是Python布尔型FalseTrue。它利用了以下事实:当用FalseTrue代替数字值时,将被强制为数字01。作为数组(或元组)索引。例如,如果表达式评估为True,则访问元组的单元格1,其包含1

该功能被映射到(熊猫?)数据帧的每一行(实际上,仅在过滤列'humidity''workingday')并且结果被存储在'sticky'柱。这就是说,你可以使用匿名functionapply翻译中的R相同的表达式:

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

(滤波可能是没有必要的,但我的[R技能是非常生疏)。

然而,实现相同的更地道的方式,为kdopen写道:

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

我已经使用int(x ['workingday'] == 1和x ['humidity']> = 60)'来将布尔转换为整数。 –

+1

现在等价于R :) – kdopen

+0

'axis = 1'表示按行 – hrbrmstr

0

我不得不说这是一个功能应用到大熊猫DF奇怪的方式,反正这是一个例子这显示了它的作用:

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 

Lambda表达式呼吁apply并通过axis=1,这意味着按行和表达是否是真还是假测试每个指定的列,该(0,1)施放这一个int,否则你会得到返回的布尔型dtype。

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 

随着(0,1)投:

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 

大熊猫的办法是做这样的:

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 

我不知道[R所以不能对此发表评论

2

地道性R等价物将是

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

假设希望得到一个指标列。

Stefano很好地解释了Python代码。拉姆达的完全展开的版本可能

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

但你永远不会写

0

一个dplyr完整的/可重复的解决方案:

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 

如果你真的需要01

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