我在python中使用pandas并希望执行以下操作: 我想在我的数据框中引入一个新的列A.为了计算它,我想考虑列B中与我的"当前元素"相同的所有行。 (我认为这是我现在陷入困境的一部分)在B栏中,然后取C列的最小值减去所有这些C的当前元素的值 - 并排除差异0,即自我-reference。
举个例子:
B C A
0 0 1.2 1.7 (calculation: possible rows are 1 and 2 (all have B = 0), the differences are 2.9 - 1.2 and 3.0 - 1.2 => min = 1.7
1 0 2.9 -1.7 (min difference is 1.2 - 2.9)
2 0 3.0 -1.8
3 1 4.1 1.4
4 1 5.5 -1.4
谢谢!
答案 0 :(得分:1)
df.groupby('B')['C'].transform(lambda x: np.where(x.idxmin() == x.index,
x.nsmallest(2).iloc[1]-x,
(x[x.idxmin()] - x)))
输出:
B C A A_new
0 0 1.2 1.7 1.7
1 0 2.9 -1.7 -1.7
2 0 3.0 -1.8 -1.8
3 1 4.1 1.4 1.4
4 1 5.5 -1.0 -1.4
IIUC,你认为你想要这个,但是我不确定A栏中的1。这是每组中的第一行。我用1替换0。
df['A_new'] = df.groupby('B')['C'].transform(lambda x: (x[x.idxmin()] - x).replace(0,1))
输出:
B C A A_new
0 0 1 1 1
1 0 2 -1 -1
2 0 3 -2 -2
3 1 4 1 1
4 1 5 -1 -1
时序:
您的解决方案:
%timeit df.apply(lambda x: df[(df.B == x.B) & (~df.C.eq(x.C))].min().C - x.C, axis=1)
100个循环,每个循环最佳3:9.78 ms
此解决方案:
%timeit df.groupby('B')['C'].transform(lambda x: np.where(x.idxmin() == x.index,1,(x[x.idxmin()] - x)))
100个循环,最佳3:每循环3.58 ms
答案 1 :(得分:1)
很难理解,但工作......
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
答案 2 :(得分:1)
转换min并减去df['new'] = (df.groupby('B')['C'].transform('min')-df['C']).replace(0,1)
B C A new
0 0 1 1 1
1 0 2 -1 -1
2 0 3 -2 -2
3 1 4 1 1
4 1 5 -1 -1
g = df.groupby('B')
diff = g['C'].transform('min') - df['C']
df['new'] = diff.where(diff!=0,np.nan)
df['new'] = df['new'].fillna(df['new'].abs().groupby(df['B']).transform('min'))
B C A new
0 0 1.2 1.7 1.7
1 0 2.9 -1.7 -1.7
2 0 3.0 -1.8 -1.8
3 1 4.1 1.4 1.4
4 1 5.5 -1.4 -1.4
根据更新的数据框进行编辑:
{{1}}
答案 3 :(得分:0)
感谢所有人提供的有用答案。 我现在的首选解决方案是:
DBMS_UTILITY.EXEC_DDL_STATEMENT('TRUNCATE TABLE tablename;');
你怎么看?
那么我得到所有更小/更大的值并且可以合并它们。