给出以下数据框:
import pandas as pd
df=pd.DataFrame({'A':[0,4,4,4],
'B':[0,4,4,0],
'C':[0,4,4,4],
'D':[4,0,0,4],
'E':[4,0,0,0],
'Name':['a','a','b','c']})
df
A B C D E Name
0 0 0 0 4 4 a
1 4 4 4 0 0 a
2 4 4 4 0 0 b
3 4 0 4 4 0 c
我想添加一个名为“Match_Flag”的新字段,如果它们具有互补的零模式(如行0,1和2),则标记行的唯一组合并且具有相同的名称(仅适用于行0和1)。它使用匹配的行的名称。
所需结果如下:
A B C D E Name Match_Flag
0 0 0 0 4 4 a a
1 4 4 4 0 0 a a
2 4 4 4 0 0 b NaN
3 4 0 4 4 0 c NaN
警告: 模式可能会有所不同,但仍应互补。
提前致谢!
更新
很抱歉这个混乱。 以下是一些澄清:
第0行和第1行是“互补”的原因是它们的列中具有相反的零模式; 0,0,0,4,4 vs,4,4,4,0,0。 数字4是任意的;它可以很容易地是0,0,0,4,2和65,770,23,0,0。因此,如果2个这样的行确实是互补的并且它们具有相同的名称,我希望它们在“Match_Flag”列下标记相同的名称。
答案 0 :(得分:2)
如果点积为零,你可以识别一个赞美,并且它的元素和为零。
def complements(df):
v = df.drop('Name', axis=1).values
n = v.shape[0]
row, col = np.triu_indices(n, 1)
# ensure two rows are complete
# their sum contains no zeros
c = ((v[row] + v[col]) != 0).all(1)
complete = set(row[c]).union(col[c])
# ensure two rows do not overlap
# their product is zero everywhere
o = (v[row] * v[col] == 0).all(1)
non_overlap = set(row[o]).union(col[o])
# we are a compliment iff we do
# not overlap and we are complete
complement = list(non_overlap.intersection(complete))
# return slice
return df.Name.iloc[complement]
然后groupby('Name')
和apply
我们的功能
df['Match_Flag'] = df.groupby('Name', group_keys=False).apply(complements)