使用apply而不是迭代将代码分配给pandas数据帧

时间:2017-10-21 15:45:07

标签: python pandas

我想根据给定行中的数字序列对数字的数据帧进行编码。数字序列本身具有我想捕捉的意义。我能够使用循环来解决这个问题,但这非常耗时。

启动df:

   2017-10-06  2017-10-07  2017-10-08
id                                                                 
1         1.0        46.0         5.0   
2        16.0         1.0         0.0   
3        23.0       123.0         0.0   
4         1.0         0.0         0.0   
5         0.0         0.0         0.0

我创建了一个我传递每列的功能。它需要知道前一列,并分配一个编码字符串。

编码的df看起来像:

   2017-10-06  2017-10-07  2017-10-08
id                                                                 
1      active      active      active   
2      active      active  inactive_1   
3      active      active  inactive_1   
4      active  inactive_1  inactive_1   
5  inactive_1  inactive_1  inactive_3

我目前能够遍历每一列,分配“活跃”列。 (很容易找到非零值),然后分配一个零的数量(如果找到零,查看前一个值并添加1,除非最后一个值是'有效',在这种情况下开始在1)

for i in range(1, len(cols)):
    test = cols[i]
    prev = cols[i-1]
    df[cols[i]] = df.apply(lambda row: assign_active(row[prev], row[test]), axis=1)

中间df看起来像:

   2017-10-06  2017-10-07  2017-10-08
id                                                                 
1      active      active      active   
2      active      active           1   
3      active      active           1   
4      active           1           2   
5           1           2           3

然后我再次迭代,以及任何不活跃的事情'使用迭代每列的相同方法并使用apply with my function来适当地编码。该函数查看特定值并分配正确的代码(您注意到没有' active_2',因此它不仅仅是操纵字符串)

我想找到一种方法来完成这项工作而不必遍历每一列,更不用说两次了。

谢谢!

1 个答案:

答案 0 :(得分:1)

IIUC,定义一个使用np.where的函数(注意,这非常快)。

def foo(s):
     return np.where(s > 0, 'active', 'inactive_' + (s.eq(0).cumsum()).astype(str))

现在,沿第一个轴调用df.apply

df = df.apply(foo, 1)
print(df)
    2017-10-06  2017-10-07  2017-10-08
id                                    
1       active      active      active
2       active      active  inactive_1
3       active      active  inactive_1
4       active  inactive_1  inactive_2
5   inactive_1  inactive_2  inactive_3

考虑到你的中间输出,这可能是你想要的。