2015-03-18 73 views
12

我有一個pandas數據幀,dfSlice熊貓數據框按標籤不在列表中

我想選擇df所有指數是在列表中沒有blacklist.

現在,我使用列表解析創建所需的標籤切片。

ix=[i for i in df.index if i not in blacklist] 
df_select=df.loc[ix] 

工作正常,但如果我經常需要這樣做可能很笨拙。

有沒有更好的方法來做到這一點?

回答

21

對指數使用isin和反轉布爾指數進行標籤的選擇:

In [239]: 

df = pd.DataFrame({'a':np.random.randn(5)}) 
df 
Out[239]: 
      a 
0 -0.548275 
1 -0.411741 
2 -1.187369 
3 1.028967 
4 -2.755030 
In [240]: 

t = [2,4] 
df.loc[~df.index.isin(t)] 
Out[240]: 
      a 
0 -0.548275 
1 -0.411741 
3 1.028967 
+1

我測試了速度與使用集合(以及多索引列表)的替代方法。這種方法快兩倍。我還可以確認它適用於MultiIndex – 2017-04-13 15:18:14

+0

另一種觀察:我使用@Hagrid67示例,發現索引「在列表中」和「不在列表中」之間的速度沒有實際差別 – 2017-04-13 15:23:11

0
import pandas as pd 
df = pd.DataFrame(data=[5,6,7,8], index=[1,2,3,4], columns=['D',]) 
blacklist = [2,3] 
#your current way ... 
ix=[i for i in df.index if i not in blacklist] 
df_select=df.loc[ix] 

# use a mask 
mask = [True if x else False for x in df.index if x not in blacklist] 
df.loc[mask] 

http://pandas.pydata.org/pandas-docs/dev/indexing.html#indexing-label 實際上,在上述和ILOC都採取一個布爾陣列,在這種情況下,mask。從現在開始,你可以重複使用這個面具,應該更有效率。

5

你可以使用set()來製作自己的原創指數和那些要刪除的區別:

df.loc[set(df.index) - set(blacklist)] 

它擁有的是簡約的,以及更易於優勢比列表理解閱讀。

+0

感謝,這種做法是很好的。 – lmart999 2015-03-19 18:49:41

0

感謝ASGM;我發現,我需要把設定成一個列表,使其與一個多指標的工作:

mi1 = pd.MultiIndex.from_tuples([("a", 1), ("a", 2), ("b", 1), ("b", 2)]) 
df1 = pd.DataFrame(data={"aaa":[1,2,3,4]}, index=mi1) 
setValid = set(df1.index) - set([("a", 2)]) 
df1.loc[list(setValid)] # works 
df1.loc[setValid] # fails 

(抱歉,無法發表評論,代表不足)