在Pandas的apply()函数中进行计数

3

我正在尝试迭代一个DataFrame,当值改变时,增加计数器,然后将一个新列设置为该值。我能够使用全局计数器使其工作,例如:

def change_ind(row):
    global prev_row
    global k

    if row['rep'] != prev_row:
        k = k+1
        prev_row = row['rep']
    return k

但是当我尝试向apply函数传递参数时,如下所示,它不再起作用。似乎每次操作新行时都会重置k、prev_row的值。有没有一种方法可以向函数传递参数并获得我想要的结果?或者有更好的方法来完成这个任务吗?

def change_ind(row, k, prev_row):    
    if row != prev_row:
        k = k+1
        prev_row = row
    return k

2
如果我理解正确的话,你可以通过 df['rep'] = (df['rep'] != df['rep'].shift()).cumsum() 来完成相同的操作。 - EdChum
这也是我的理解,@EdChum应该把它放在答案中。另外顺便提一下,以后你可以使用k += 1来增加计数器。 - Jeff
1个回答

3

您可以使用shiftcumsum来实现相同的功能,这比循环要快得多:

In [107]:
df = pd.DataFrame({'rep':[0,1,1,1,2,3,2,3,4,5,1]})
df

Out[107]:
    rep
0     0
1     1
2     1
3     1
4     2
5     3
6     2
7     3
8     4
9     5
10    1

In [108]:    
df['rep_f'] = (df['rep']!=df['rep'].shift()).cumsum()-1
df

Out[108]:
    rep  rep_f
0     0      0
1     1      1
2     1      1
3     1      1
4     2      2
5     3      3
6     2      4
7     3      5
8     4      6
9     5      7
10    1      8

有趣!我一定会用这个的。我正在使用很多这些函数,所以我仍然好奇是否有一种方法可以将非全局变量传递给应用函数,并且不会在每次迭代中被覆盖。虽然我还需要考虑如何在未来使用shift。 - Chris Hedenberg
假设您在函数外声明了 k,那么它应该会更新,对吗?k = 0 prev_row = 0 def change_ind(row): if row != prev_row: k = k+1 prev_row = row return k - EdChum
是的,确实如此。每次调用函数都要重新声明这些变量很麻烦,所以我希望可以通过apply函数传递它们。 - Chris Hedenberg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接