使用值列表从pandas数据框中选择行

zac*_*ach 603 python dataframe pandas

可能重复:
如何通过"within"/"in"过滤pandas的数据帧行?

假设我有以下pandas数据帧:

df = DataFrame({'A' : [5,6,3,4], 'B' : [1,2,3, 5]})
df

     A   B
0    5   1
1    6   2
2    3   3
3    4   5
Run Code Online (Sandbox Code Playgroud)

我可以根据特定值进行子集化:

x = df[df['A'] == 3]
x

     A   B
2    3   3
Run Code Online (Sandbox Code Playgroud)

但是我如何根据值列表进行子集化? - 这样的事情:

list_of_values = [3,6]

y = df[df['A'] in list_of_values]
Run Code Online (Sandbox Code Playgroud)

Wou*_*ire 968

这确实是如何通过"within"/"in"过滤pandas的数据帧行的重复,将响应翻译成你的例子给出:

In [1]: df = pd.DataFrame({'A': [5,6,3,4], 'B': [1,2,3,5]})

In [2]: df
Out[2]:
   A  B
0  5  1
1  6  2
2  3  3
3  4  5

In [3]: df[df['A'].isin([3, 6])]
Out[3]:
   A  B
1  6  2
2  3  3
Run Code Online (Sandbox Code Playgroud)

  • 您将如何按列表的顺序返回这些值?例如,`list_of_values`的值为3然后是6,但是帧返回6然后是3.我不是在谈论一个简单的排序,而是我们如何具体地按照列表中的值的顺序返回. (13认同)
  • 您也可以使用'query'和@ <您的值列表>来获得类似的结果:例如:df = pd.DataFrame({'A':[1,2,3],'B':['a', 'b','f']})df = pd.DataFrame({'A':[5,6,3,4],'B':[1,2,3,5]})list_of_values = [3 ,6] result = df.query("@ in_list_of_values")结果AB 1 6 2 2 3 3 (3认同)
  • @JasonStrimpel我在这里回答了您的问题:/sf/ask/3636081501/#51944022 (2认同)

cot*_*ail 24

list_of_values不一定是list; 它可以是settupledictionary、 numpy 数组、pandas 系列、生成器range等,并且isin()query()仍然可以工作。

关于query()

选择行的一些常见问题

1.list_of_values是一个范围

如果需要在某个范围内进行过滤,可以使用between()方法 或query()

list_of_values = [3, 4, 5, 6] # a range of values

df[df['A'].between(3, 6)]  # or
df.query('3<=A<=6')
Run Code Online (Sandbox Code Playgroud)

2.df按顺序返回list_of_values

在 OP 中, 中的值list_of_values不会按 中的顺序出现df。如果您想df按它们出现的顺序返回list_of_values,即“排序” list_of_values,请使用loc

list_of_values = [3, 6]
df.set_index('A').loc[list_of_values].reset_index()
Run Code Online (Sandbox Code Playgroud)

如果你想保留旧的索引,可以使用以下内容。

list_of_values = [3, 6, 3]
df.reset_index().set_index('A').loc[list_of_values].reset_index().set_index('index').rename_axis(None)
Run Code Online (Sandbox Code Playgroud)

3.不要使用apply

一般来说,isin()query()是完成此任务的最佳方法;没有必要apply()。例如,对于f(A) = 2*A - 5列 上的函数A, 和isin()query()工作效率都要高得多:

df[(2*df['A']-5).isin(list_of_values)]         # or
df[df['A'].mul(2).sub(5).isin(list_of_values)] # or
df.query("A.mul(2).sub(5) in @list_of_values")
Run Code Online (Sandbox Code Playgroud)

4. 选择不在其中的行list_of_values

要选择不在 中的行list_of_values,请对isin()/取反in

df[~df['A'].isin(list_of_values)]
df.query("A not in @list_of_values")  # df.query("A != @list_of_values")
Run Code Online (Sandbox Code Playgroud)

5. 选择多列所在的行list_of_values

如果您想使用两个(或多个)列进行过滤,可以any()根据需要all()减少列 ( )。axis=1

  1. 选择至少包含A或之一的行: Blist_of_values
    df[df[['A','B']].isin(list_of_values).any(1)]
    df.query("A in @list_of_values or B in @list_of_values")
    
    Run Code Online (Sandbox Code Playgroud)
  2. A选择和都B位于的行list_of_values
    df[df[['A','B']].isin(list_of_values).all(1)] 
    df.query("A in @list_of_values and B in @list_of_values")
    
    Run Code Online (Sandbox Code Playgroud)


Myk*_*tko 16

您可以使用方法查询

df.query('A in [6, 3]')
# df.query('A == [6, 3]')
Run Code Online (Sandbox Code Playgroud)

或者

lst = [6, 3]
df.query('A in @lst')
# df.query('A == @lst')
Run Code Online (Sandbox Code Playgroud)

  • @Hammad 根据 Pandas 文档:“对于大帧,使用 numexpr 的 DataFrame.query() 比 Python 稍快。” (7认同)
  • 我想知道“query()”在计算上是否比“isin()”函数更好 (6认同)
  • @Hammad我做了一些测试,对于超过 10k 行的数据帧,“查询”比布尔索引更快(查看[此答案](/sf/answers/5163340171/)以获取更多信息)。 (5认同)

小智 13

您可以将值存储在列表中,如下所示:

lis = [3,6]

然后

df1 = df[df['A'].isin(lis)]

  • 和最佳答案有什么区别? (3认同)

Ach*_*age 10

另一种方法;

df.loc[df.apply(lambda x: x.A in [3,6], axis=1)]
Run Code Online (Sandbox Code Playgroud)

与isin方法不同,这在确定列表是否包含列的函数时特别有用A。例如,f(A) = 2*A - 5作为函数;

df.loc[df.apply(lambda x: 2*x.A-5 in [3,6], axis=1)]
Run Code Online (Sandbox Code Playgroud)

需要注意的是,这种方法比isin方法慢。


归档时间:

查看次数:

557372 次

最近记录:

6 年 前