2015-03-18 30 views
12

Tôi có một khung hình pandas, df.Slice Pandas dataframe theo nhãn không có trong danh sách

Tôi muốn chọn tất cả các chỉ số trong dfkhông trong một danh sách, blacklist.

Bây giờ, tôi sử dụng danh sách hiểu biết để tạo ra các nhãn mong muốn để cắt.

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

Hoạt động tốt, nhưng có thể vụng về nếu tôi cần thực hiện việc này thường xuyên.

Có cách nào tốt hơn để thực hiện việc này không?

Trả lời

21

Sử dụng isin trên chỉ mục và đảo ngược chỉ số boolean để thực hiện lựa chọn nhãn:

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

Tôi đã thử nghiệm điều này cho tốc độ chống lại sự thay thế của việc sử dụng bộ (và danh sách cho đa lập chỉ mục). Phương pháp này nhanh hơn gấp 2 lần. Tôi cũng có thể xác nhận nó hoạt động cho MultiIndex –

+0

Một quan sát khác: Tôi đã sử dụng ví dụ @ Hagrid67 và thấy không có sự khác biệt thực sự về tốc độ giữa việc lập chỉ mục "trong danh sách" và "không có trong danh sách" –

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 trên thực tế, loc và iloc cả mất một mảng boolean, trong trường hợp này mask. từ bây giờ bạn có thể tái sử dụng mặt nạ này và sẽ hiệu quả hơn.

5

Bạn có thể sử dụng set() để tạo ra sự khác biệt giữa các chỉ số ban đầu của bạn và những người mà bạn muốn loại bỏ:

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

Nó có lợi thế là tiêu dùng tiết kiệm, cũng như là dễ dàng hơn để đọc hơn là một sự hiểu biết danh sách .

+0

Cảm ơn, phương pháp này là tốt đẹp. – lmart999

0

Nhờ ASGM; Tôi thấy rằng tôi cần thiết để biến các thiết lập thành một danh sách việc cần làm cho nó làm việc với một MultiIndex:

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 

(xin lỗi không thể bình luận, không đủ đại diện)

Các vấn đề liên quan