2016-11-21 235 views
3

條件更換行的價值。這是我的熊貓數據框:在大熊貓數據幀

ID START END SEQ 
1 11  12 5 
1 14  15 6 
1 13  14 7 
2 10  14 1 
3 11  15 1 
3 16  17 2 

我想改變序列的值,以便爲同一ID的SEQ值是1,2,...等等,例如

ID START END SEQ 
1 11  12 1 
1 14  15 3 
1 13  14 2 
2 10  14 1 
3 11  15 1 
3 16  17 2 

我怎樣纔能有效地避免循環?在GROUPBY操作

回答

0

添加一點點,以Boud的答案,如果你打算什麼是有在造成SEQ列的順序取決於起始列的值,可以通過

df['SEQ'] = df.sort_values(by='START').groupby('ID').cumcount()+1 

也就是實現這一目標,

In [3]: df 
Out[3]: 
    ID START END SEQ 
0 1  11 12 5 
1 1  14 15 6 
2 1  13 14 7 
3 2  10 14 1 
4 3  11 15 1 
5 3  16 17 2 

In [4]: df['SEQ'] = df.sort_values(by='START').groupby('ID').cumcount()+1 

In [5]: df 
Out[5]: 
    ID START END SEQ 
0 1  11 12 1 
1 1  14 15 3 
2 1  13 14 2 
3 2  10 14 1 
4 3  11 15 1 
5 3  16 17 2 
1

使用cumcount:

df.groupby('ID').cumcount()+1 
0

這裏有兩個approac使用np.cumsumNumPy HES創建這些斜坡陣列 -

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() 

運行測試 -

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看看它是如何工作的 -

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