, ...
df['new'] = df.B.map(df.groupby('B').C.apply(list))
df.apply(lambda x :min(list(map(lambda y: y - x['C'],list(set(x['new'])-set([x['C']]))))),axis=1)
Out[1013]:
0 1
1 -1
2 -2
3 1
4 -1
dtype: int64
:
df['NewA']=df.apply(lambda x :min(list(map(lambda y: y - x['C'],list(set(x['new'])-set([x['C']]))))),axis=1)
df
Out[1015]:
B C A new NewA
0 0 1 1 [1, 2, 3] 1
1 0 2 -1 [1, 2, 3] -1
2 0 3 -2 [1, 2, 3] -2
3 1 4 1 [4, 5] 1
4 1 5 -1 [4, 5] -1
numpy
A = df.C.values[:, None] - df.C.values.T
np.fill_diagonal(A, 9999999)
G=df.groupby('B')
np.concatenate([np.min(A[y.min():y.max()+1,y.min():y.max()+1],0) for _, y in G.groups.items()])
%timeit df.apply(lambda x: df[(df.B == x.B) & (~df.C.eq(x.C))].min().C - x.C, axis=1)
100 loops, best of 3: 4.14 ms per loop
%timeit df.groupby('B')['C'].transform(lambda x: np.where(x.idxmin() == x.index,1,(x[x.idxmin()] - x)))
100 loops, best of 3: 1.67 ms per loop
def fff(x):
A = df.C.values[:, None] - df.C.values.T
np.fill_diagonal(A, 9999999)
G=df.groupby('B')
np.concatenate([np.min(A[y.min():y.max()+1,y.min():y.max()+1],0) for _, y in G.groups.items()])
%timeit fff(1)
1000 loops, best of 3: 758 µs per loop