按不在列表中的标签切片Pandas数据帧

时间:2015-03-18 23:31:27

标签: python pandas

我有一个pandas数据框,df

我想在df中选择列表中的所有索引blacklist.

现在,我使用list comprehension创建所需的标签以进行切片。

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

工作正常,但如果我需要经常这样做,可能会很笨拙。

有更好的方法吗?

6 个答案:

答案 0 :(得分:44)

在索引上使用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 :(得分:10)

您可以使用set()创建原始索引与要删除的索引之间的差异:

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

它具有简约的优点,并且比列表理解更容易阅读。

答案 2 :(得分:1)

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 实际上,loc和iloc都采用布尔数组,在本例中为mask。从现在开始,你可以重复使用这个掩码,并且应该更有效率。

答案 3 :(得分:0)

感谢ASGM;我发现我需要将集合转换为列表才能使其与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

(抱歉无法评论,代表不足)

答案 4 :(得分:0)

如果您正在寻找一种选择条件之外的所有行的方法,则可以使用np.invert(),条件是该条件返回布尔数组。

df.loc[np.invert(({condition 1}) & (condition 2))]

答案 5 :(得分:0)

df = pd.DataFrame(data=[5,6,7,8], index=[1,2,3,4], columns=['D',])
blacklist = [2,3]

df.drop(blacklist,0)