我会在布尔数组上使用 argmax
。此外,如果我直接使用 numpy
可以使其更快。
(df.values[:, ::-1] != 0).argmax(1)
array([1, 3, 0, 2])
或者非常类似地
(df.values[:, ::-1].astype(bool)).argmax(1)
array([1, 3, 0, 2])
我可以使用assign
将其放置在新的列中。
df.assign(new=(df.values[:, ::-1] != 0).argmax(1))
C1 C2 C3 C4 new
0 1 2 3 0 1
1 4 0 0 0 3
2 0 0 0 3 0
3 0 3 0 0 2
在原地添加一个新列:
或者在原地添加一个新的列
df['new'] = (df.values[:, ::-1] != 0).argmax(1)
df
C1 C2 C3 C4 new
0 1 2 3 0 1
1 4 0 0 0 3
2 0 0 0 3 0
3 0 3 0 0 2
时序
我们通过减少必要的工作来缩短时间。我们只需要找到第一个非零位的位置。
%timeit df.assign(new=(df.values[:, ::-1] != 0).argmax(1))
%timeit df.assign(new=(df.values[:, ::-1].astype(bool)).argmax(1))
%timeit df.assign(new=df.iloc[:,::-1].cumsum(1).eq(0).sum(1))
%timeit df.assign(new=(df.values[:,::-1].cumsum(1) == 0).sum(1))
%timeit df.assign(new=df.iloc[:,::-1].eq(0).cumprod(axis=1).sum(axis=1))
%timeit df.assign(new=(df.values[:,::-1] == 0).cumprod(1).sum(1))
small data
1000 loops, best of 3: 301 µs per loop
1000 loops, best of 3: 273 µs per loop
1000 loops, best of 3: 770 µs per loop
1000 loops, best of 3: 323 µs per loop
1000 loops, best of 3: 647 µs per loop
1000 loops, best of 3: 324 µs per loop
更大的数据
df = pd.DataFrame(np.random.choice([0, 1], (10000, 100), p=(.7, .3)))
100 loops, best of 3: 6.03 ms per loop
100 loops, best of 3: 5.3 ms per loop
100 loops, best of 3: 16.9 ms per loop
100 loops, best of 3: 9 ms per loop
100 loops, best of 3: 10.7 ms per loop
100 loops, best of 3: 10.1 ms per loop
3,2,1
,并且它计算为0+3, 0+3+2, 0+3+2+1
。 - jezrael0,0+0, 0+0+3, 0+0+3+0
。 - jezrael