[英]Slice Pandas dataframe by index values that are (not) in a list
I have a pandas
dataframe, df
.我有一个
pandas
dataframe, df
。
I want to select all indices in df
that are not in a list, blacklist.
我想要 select
df
中不在列表、 blacklist.
Now, I use list comprehension to create the desired labels to slice.现在,我使用列表理解来创建所需的切片标签。
ix=[i for i in df.index if i not in blacklist]
df_select=df.loc[ix]
Works fine, but may be clumsy if I need to do this often.工作正常,但如果我需要经常这样做可能会很笨拙。
Is there a better way to do this?有一个更好的方法吗?
Use isin
on the index and invert the boolean index to perform label selection:在索引上使用
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
You could use set()
to create the difference between your original indices and those that you want to remove:您可以使用
set()
来创建原始索引和要删除的索引之间的差异:
df.loc[set(df.index) - set(blacklist)]
It has the advantage of being parsimonious, as well as being easier to read than a list comprehension.它的优点是简洁,并且比列表理解更容易阅读。
Thanks to ASGM;感谢 ASGM; I found that I needed to turn the set into a list to make it work with a MultiIndex:
我发现我需要将集合变成一个列表才能使其与 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
(sorry can't comment, insufficient rep) (抱歉不能评论,代表不足)
You could use difference() to obtain the difference between your original indices and those that you want to exclude:您可以使用 difference() 来获取原始索引与要排除的索引之间的差异:
df.loc[df.index.difference(blacklist), :]
It has the advantage of being easier to read.它的优点是更容易阅读。
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 actually, loc and iloc both take a boolean array, in this case the mask
. http://pandas.pydata.org/pandas-docs/dev/indexing.html#indexing-label实际上, loc 和 iloc 都采用布尔数组,在这种情况下为
mask
。 from now on you can reuse this mask and should be more efficient.从现在开始你可以重复使用这个面具,应该会更有效率。
如果您正在寻找一种选择条件之外的所有行的方法,您可以使用np.invert()
,因为条件返回一个布尔数组。
df.loc[np.invert(({condition 1}) & (condition 2))]
df = pd.DataFrame(data=[5,6,7,8], index=[1,2,3,4], columns=['D',])
blacklist = [2,3]
df.drop(blacklist,0)
You can use the np.setdiff1d
function which finds the set difference of two arrays.您可以使用
np.setdiff1d
function 找到两个 arrays 的集合差异。
index = np.array(blacklist)
not_index = np.setdiff1d(df.index.to_numpy(), index)
df.iloc[not_index]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.