如何根据Pandas中某列的值从DataFrame中选择行?
在SQL中,我会使用:
SELECT *
FROM table
WHERE column_name = some_value
如何根据Pandas中某列的值从DataFrame中选择行?
在SQL中,我会使用:
SELECT *
FROM table
WHERE column_name = some_value
当前回答
使用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
其他回答
使用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
使用numpy.where可以获得更快的结果。
例如,使用unubtu的设置-
In [76]: df.iloc[np.where(df.A.values=='foo')]
Out[76]:
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
时间比较:
In [68]: %timeit df.iloc[np.where(df.A.values=='foo')] # fastest
1000 loops, best of 3: 380 µs per loop
In [69]: %timeit df.loc[df['A'] == 'foo']
1000 loops, best of 3: 745 µs per loop
In [71]: %timeit df.loc[df['A'].isin(['foo'])]
1000 loops, best of 3: 562 µs per loop
In [72]: %timeit df[df.A=='foo']
1000 loops, best of 3: 796 µs per loop
In [74]: %timeit df.query('(A=="foo")') # slowest
1000 loops, best of 3: 1.71 ms per loop
使用带有panda>=0.25.00的.query更灵活:
由于panda>=0.25.00,我们可以使用查询方法来使用panda方法过滤数据帧,甚至可以使用带有空格的列名。通常,列名中的空格会给出一个错误,但现在我们可以使用backtick(`)来解决这个问题-请参见GitHub:
# Example dataframe
df = pd.DataFrame({'Sender email':['ex@example.com', "reply@shop.com", "buy@shop.com"]})
Sender email
0 ex@example.com
1 reply@shop.com
2 buy@shop.com
将.query与方法str.endswith一起使用:
df.query('`Sender email`.str.endswith("@shop.com")')
输出
Sender email
1 reply@shop.com
2 buy@shop.com
此外,我们还可以通过在查询中用@前缀来使用局部变量:
domain = 'shop.com'
df.query('`Sender email`.str.endswith(@domain)')
输出
Sender email
1 reply@shop.com
2 buy@shop.com
如果您想重复查询数据帧,并且速度对您很重要,最好的方法是将数据帧转换为字典,然后通过这样做,您可以将查询速度提高数千倍。
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]
对于Pandas中给定值的多个列中仅选择特定列:
select col_name1, col_name2 from table where column_name = some_value.
选项位置:
df.loc[df['column_name'] == some_value, [col_name1, col_name2]]
或查询:
df.query('column_name == some_value')[[col_name1, col_name2]]