2017-09-14 52 views
2

背景:我有一個表示兩點之間距離的矩陣。在這個矩陣中,行和列都是數據點。例如:基於值以批處理方式拖放熊貓數據幀行和列

A B C 
A 0 999 3 
B 999 0 999 
C 3 999 0 

在這個玩具的例子中,假設我想拋棄C出於某種原因,因爲它離任何其他點都很遠。所以我第一次聚集數:

df["far_count"] = df[df == 999].count() 

,然後批量刪除:

df = df[df["far_count"] == 2] 

在這個例子中,這看起來有點多餘,但請想象,我有很多的數據點是這樣的(比如說在順序爲10Ks)

上述批次移除的問題是我想在同一時間(而不是僅行)移除行和列,而且我不清楚如何優雅地進行。一個天真的辦法是讓這些數據點的列表,並把它放在一個循環,然後:

for item in list: 
    df.drop(item, axis=1).drop(item, axis=0) 

但我不知道是否有更好的方法。 (獎金,如果我們能跳過隨中級步far_count

回答

2
np.random.seed([3,14159]) 
idx = pd.Index(list('ABCDE')) 
a = np.random.randint(3, size=(5, 5)) 
df = pd.DataFrame(
    a.T.dot(a) * (1 - np.eye(5, dtype=int)), 
    idx, idx) 

df 

    A B C D E 
A 0 4 2 4 2 
B 4 0 1 5 2 
C 2 1 0 2 6 
D 4 5 2 0 3 
E 2 2 6 3 0 

l = ['A', 'C'] 
m = df.index.isin(l) 

df.loc[~m, ~m] 

    B D E 
B 0 5 2 
D 5 0 3 
E 2 3 0 

針對您的特殊情況下,由於陣列是對稱的,你只需要檢查一個維度。

m = (df.values == 999).sum(0) == len(df) - 1 
2
In [66]: x = pd.DataFrame(np.triu(df), df.index, df.columns) 

In [67]: x 
Out[67]: 
    A B C 
A 0 999 3 
B 0 0 999 
C 0 0 0 

In [68]: mask = x.ne(999).all(1) | x.ne(999).all(0) 

In [69]: df.loc[mask, mask] 
Out[69]: 
    A C 
A 0 3 
C 3 0