如何根据Pandas中某列的值从DataFrame中选择行?

在SQL中,我会使用:

SELECT *
FROM table
WHERE column_name = some_value

当前回答

您也可以使用.apply:

df.apply(lambda row: row[df['B'].isin(['one','three'])])

它实际上按行工作(即,将函数应用于每一行)。

输出为

   A      B  C   D
0  foo    one  0   0
1  bar    one  1   2
3  bar  three  3   6
6  foo    one  6  12
7  foo  three  7  14

结果与@unsubu提到的使用相同

df[[df['B'].isin(['one','three'])]]

其他回答

使用DuckDB选择行的DataFrames上的SQL语句

使用DuckDB,我们可以用SQL语句以高性能的方式查询panda DataFrames。

由于问题是如何根据列值从DataFrame中选择行?,问题中的示例是一个SQL查询,这个答案在本主题中看起来很合理。

例子:

In [1]: import duckdb

In [2]: import pandas as pd

In [3]: con = duckdb.connect()

In [4]: df = pd.DataFrame({"A": range(11), "B": range(11, 22)})

In [5]: df
Out[5]:
     A   B
0    0  11
1    1  12
2    2  13
3    3  14
4    4  15
5    5  16
6    6  17
7    7  18
8    8  19
9    9  20
10  10  21

In [6]: results = con.execute("SELECT * FROM df where A > 2").df()

In [7]: results
Out[7]:
    A   B
0   3  14
1   4  15
2   5  16
3   6  17
4   7  18
5   8  19
6   9  20
7  10  21

在Pandas的更新版本中,受文档启发(查看数据):

df[df["colume_name"] == some_value] #Scalar, True/False..

df[df["colume_name"] == "some_value"] #String

通过将子句放在括号()中,并用&和|(和/或)组合来组合多个条件。这样地:

df[(df["colume_name"] == "some_value1") & (pd[pd["colume_name"] == "some_value2"])]

其他过滤器

pandas.notna(df["colume_name"]) == True # Not NaN
df['colume_name'].str.contains("text") # Search for "text"
df['colume_name'].str.lower().str.contains("text") # Search for "text", after converting  to lowercase

要选择列值等于标量some_value的行,请使用==:

df.loc[df['column_name'] == some_value]

要选择列值在可迭代的some_values中的行,请使用isin:

df.loc[df['column_name'].isin(some_values)]

将多个条件与&组合:

df.loc[(df['column_name'] >= A) & (df['column_name'] <= B)]

注意括号。由于Python的运算符优先级规则,&binding比<=和>=更紧密。因此,最后一个示例中的括号是必要的。没有括号

df['column_name'] >= A & df['column_name'] <= B

解析为

df['column_name'] >= (A & df['column_name']) <= B

这导致序列的真值是模糊错误。


要选择列值不等于some_value的行,请使用!=:

df.loc[df['column_name'] != some_value]

isin返回布尔级数,因此要选择值不在some_values中的行,请使用~:

df.loc[~df['column_name'].isin(some_values)]

例如

import pandas as pd
import numpy as np
df = pd.DataFrame({'A': 'foo bar foo bar foo bar foo foo'.split(),
                   'B': 'one one two three two two one three'.split(),
                   'C': np.arange(8), 'D': np.arange(8) * 2})
print(df)
#      A      B  C   D
# 0  foo    one  0   0
# 1  bar    one  1   2
# 2  foo    two  2   4
# 3  bar  three  3   6
# 4  foo    two  4   8
# 5  bar    two  5  10
# 6  foo    one  6  12
# 7  foo  three  7  14

print(df.loc[df['A'] == 'foo'])

产量

     A      B  C   D
0  foo    one  0   0
2  foo    two  2   4
4  foo    two  4   8
6  foo    one  6  12
7  foo  three  7  14

如果要包含多个值,请将它们放入列出(或更一般地,任何可迭代的)并使用isin:

print(df.loc[df['B'].isin(['one','three'])])

产量

     A      B  C   D
0  foo    one  0   0
1  bar    one  1   2
3  bar  three  3   6
6  foo    one  6  12
7  foo  three  7  14

但是,请注意,如果您希望多次这样做首先创建索引,然后使用df.loc:

df = df.set_index(['B'])
print(df.loc['one'])

产量

       A  C   D
B              
one  foo  0   0
one  bar  1   2
one  foo  6  12

或者,要包含索引中的多个值,请使用df.index.isin:

df.loc[df.index.isin(['one','two'])]

产量

       A  C   D
B              
one  foo  0   0
one  bar  1   2
two  foo  2   4
two  foo  4   8
two  bar  5  10
one  foo  6  12

如果您想重复查询数据帧,并且速度对您很重要,最好的方法是将数据帧转换为字典,然后通过这样做,您可以将查询速度提高数千倍。

my_df = df.set_index(column_name)
my_dict = my_df.to_dict('index')

制作my_dict字典后,您可以浏览:

if some_value in my_dict.keys():
   my_result = my_dict[some_value]

如果column_name中有重复值,则无法创建字典。但您可以使用:

my_result = my_df.loc[some_value]

tl;博士

熊猫相当于

select * from table where column_name = some_value

is

table[table.column_name == some_value]

多种条件:

table[(table.column_name == some_value) | (table.column_name2 == some_value2)]

or

table.query('column_name == some_value | column_name2 == some_value2')

代码示例

import pandas as pd

# Create data set
d = {'foo':[100, 111, 222],
     'bar':[333, 444, 555]}
df = pd.DataFrame(d)

# Full dataframe:
df

# Shows:
#    bar   foo
# 0  333   100
# 1  444   111
# 2  555   222

# Output only the row(s) in df where foo is 222:
df[df.foo == 222]

# Shows:
#    bar  foo
# 2  555  222

在上面的代码中,是df[df.foo==222]行根据列值给出行,在本例中为222。

也可能出现多种情况:

df[(df.foo == 222) | (df.bar == 444)]
#    bar  foo
# 1  444  111
# 2  555  222

但在这一点上,我建议使用查询函数,因为它不那么冗长,并产生相同的结果:

df.query('foo == 222 | bar == 444')