は2 approacあり、
ある
df['SEQ'] = df.sort_values(by='START').groupby('ID').cumcount()+1
を介してこれを実現
def id_ramp(a):
out = np.ones(a.size,dtype=int)
idx = np.nonzero(np.append(True,a[1:] > a[:-1]))[0]
out[idx[1:]] = -idx[1:] + idx[:-1] + 1
return out.cumsum()
def id_ramp2(a):
out = np.ones(a.size,dtype=int)
idx = np.nonzero(a[1:] > a[:-1])[0]+1
out[idx[0]] = -idx[0]+1
out[idx[1:]] = idx[:-1] - idx[1:]+1
return out.cumsum()
ランタイムテスト - - それらのランプ配列を作成するためにnp.cumsum
を使用してNumPy
とHES
In [381]: a = np.sort(np.random.randint(1,100,(1000)))
In [382]: df = pd.DataFrame(a, columns=[['ID']])
In [383]: %timeit df['SEQ'] = df.groupby('ID').cumcount()+1 #@Boud's soln
100 loops, best of 3: 2.01 ms per loop
In [384]: %timeit df['SEQ'] = id_ramp(df.ID.values)
1000 loops, best of 3: 315 µs per loop
In [385]: %timeit df['SEQ'] = id_ramp2(df.ID.values)
1000 loops, best of 3: 304 µs per loop
あなたは常にソートされていないID
列を使用している場合、私たちはそこにいくつかのargsort
を使用する必要があります、ように -
a = df.ID.values
sidx = a.argsort(kind='mergesort')
df['SEQ'] = id_ramp2(a[sidx])[sidx.argsort()]
サンプルcを見てみましょうどのように動作するか見るためにase -
In [447]: df
Out[447]:
ID
0 1
1 1
2 7
3 5
4 3
5 8
6 1
7 3
8 7
9 2
10 5
11 7
In [448]: a = df.ID.values
...: sidx = a.argsort(kind='mergesort')
...: df['SEQ'] = id_ramp2(a[sidx])[sidx.argsort()]
...:
In [449]: df
Out[449]:
ID SEQ
0 1 1
1 1 2
2 7 1
3 5 1
4 3 1
5 8 1
6 1 3
7 3 2
8 7 2
9 2 1
10 5 2
11 7 3