2016-08-08 98 views
2

鑑於以下數據幀:熊貓標誌行與互補零

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)AND具有相同的名稱(僅用於行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 

警告: 的模式可以不同,但​​仍應是互補的。

在此先感謝!

UPDATE

很抱歉的混亂。 這裏有一些說明:

行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

從來沒有的 「免費」 的頭,請解釋。 – Merlin

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

enter image description here

+1

我認爲點積爲零是必要條件,但還不夠。 OP的評論說「一行中零的列在另一行中不爲零」。由此看來,如果兩行在同一列中具有零,它們不是互補的,但可以具有零的點積,例如, '[4,0,0]'和'[0,0,4]'。如果存在負值,即使所有條目都不爲零,也可以得到零點產品,例如, '[1,-1,1]'和'[1,2,1]'。 – root

+0

@root修復它。 – piRSquared