对 pandas 数据集执行 SQL 查询

问题描述 投票:0回答:9

我有一个 pandas 数据集,名为“df”。

我怎样才能做如下的事情;

df.query("select * from df")

谢谢你。

对于那些了解 R 的人来说,有一个名为 sqldf 的库,您可以在 R 中执行 SQL 代码,我的问题基本上是,Python 中是否有像 sqldf 这样的库

python sqlite pandas
9个回答
141
投票

这不是

pandas.query
应该做的。你可以查看包
pandasql
(与R中的
sqldf
相同)

编辑:注意 pandasql 自 2017 年以来就没有维护过。使用下面答案中的另一个库。

import pandas as pd
import pandasql as ps

df = pd.DataFrame([[1234, 'Customer A', '123 Street', np.nan],
               [1234, 'Customer A', np.nan, '333 Street'],
               [1233, 'Customer B', '444 Street', '333 Street'],
              [1233, 'Customer B', '444 Street', '666 Street']], columns=
['ID', 'Customer', 'Billing Address', 'Shipping Address'])

q1 = """SELECT ID FROM df """

print(ps.sqldf(q1, locals()))

     ID
0  1234
1  1234
2  1233
3  1233

更新2020-07-10

更新

pandasql

ps.sqldf("select * from df")

39
投票

更好的解决方案是使用 duckdb。它比 sqldf 快得多,因为它不必将整个数据加载到 sqlite 中并加载回 pandas。

pip install duckdb
import pandas as pd
import duckdb
test_df = pd.DataFrame.from_dict({"i":[1, 2, 3, 4], "j":["one", "two", "three", "four"]})

duckdb.query("SELECT * FROM test_df where i>2").df() # returns a result dataframe

相对于 pandasql 的性能改进: 测试数据 NYC 黄色出租车 ~120mb 的 csv 数据

nyc = pd.read_csv('https://s3.amazonaws.com/nyc-tlc/trip+data/yellow_tripdata_2021-01.csv',low_memory=False)
from pandasql import sqldf
pysqldf = lambda q: sqldf(q, globals())
pysqldf("SELECT * FROM nyc where trip_distance>10")
# wall time 16.1s
duckdb.query("SELECT * FROM nyc where trip_distance>10").df()
# wall time 183ms

速度提高约 100 倍

这篇文章提供了很好的细节,并声称比 pandasql 提高了 1000 倍: https://duckdb.org/2021/05/14/sql-on-pandas.html


29
投票

使用一段时间后,我意识到最简单的方法就是这样做

from pandasql import sqldf

output = sqldf("select * from df")

就像一个魅力,其中

df
是一个pandas数据框 您可以安装pandasql:https://pypi.org/project/pandasql/


6
投票

实际上我刚刚发布了一个新包,名为 dataframe_sql。这使您能够按照您的意愿使用 SQL 查询 pandas 数据帧。您可以在这里

找到该包

5
投票

您可以使用

DataFrame.query(condition)
返回与
condition
匹配的数据框子集,如下所示:

df = pd.DataFrame(np.arange(9).reshape(3,3), columns=list('ABC'))
df
   A  B  C
0  0  1  2
1  3  4  5
2  6  7  8

df.query('C < 6')
   A  B  C
0  0  1  2
1  3  4  5


df.query('2*B <= C')
   A  B  C
0  0  1  2


df.query('A % 2 == 0')
   A  B  C
0  0  1  2
2  6  7  8

这与 SQL 语句的效果基本相同,只是隐含了

SELECT * FROM df WHERE


2
投票

我认为比

pandassql
更好的解决方案是 duckdb。在我看来,它处理表名映射到数据框对象的方式更干净一些。不过我还没有评估过性能。


1
投票

或者,您可以使用最擅长的工具:

  1. 安装postgresql

  2. 连接数据库:

从 sqlalchemy 导入 create_engine
导入 urllib.parse
engconnect = "{0}://{1}:{2}@{3}:{4}/{5}".format(方言,user_uenc, pw_uenc, 主机,端口, dbname)
dbengine = create_engine(engconnect)
数据库 = dbengine.connect()

  1. 将数据帧转储到 postgres 中

df.to_sql('mytablename', 数据库, if_exists='替换')

  1. 使用您的大脑可以处理的所有 SQL 嵌套来编写查询。

myquery =“从 mytablename 中选择不同的 *”

  1. 通过运行查询创建数据框:

newdf = pd.read_sql(myquery, 数据库)


1
投票

还有FugueSQL

pip install fugue[sql]
import pandas as pd
from fugue_sql import fsql

comics_df = pd.DataFrame({'book': ['Secret Wars 8',
                                   'Tomb of Dracula 10',
                                   'Amazing Spider-Man 252',
                                   'New Mutants 98',
                                   'Eternals 1',
                                   'Amazing Spider-Man 300',
                                   'Department of Truth 1'],
                          'publisher': ['Marvel', 'Marvel', 'Marvel', 'Marvel', 'Marvel', 'Marvel', 'Image'],
                          'grade': [9.6, 5.0, 7.5, 8.0, 9.2, 6.5, 9.8],
                          'value': [400, 2500, 300, 600, 400, 750, 175]})

# which of my books are graded above 8.0?
query = """
SELECT book, publisher, grade, value FROM comics_df
WHERE grade > 8.0
PRINT
"""

fsql(query).run()

输出

PandasDataFrame
book:str                                                      |publisher:str|grade:double|value:long
--------------------------------------------------------------+-------------+------------+----------
Secret Wars 8                                                 |Marvel       |9.6         |400       
Eternals 1                                                    |Marvel       |9.2         |400       
Department of Truth 1                                         |Image        |9.8         |175       
Total count: 3

参考文献

https://fugue-tutorials.readthedocs.io/tutorials/beginner/beginner_sql.html

https://www.kdnuggets.com/2021/10/query-pandas-dataframes-sql.html


0
投票

另一个解决方案是RBQL,它提供类似 SQL 的查询语言,允许在 SELECT 和 WHERE 语句中使用 Python 表达式。它还提供了一个方便的

%rbql
魔法命令,可以在 Jupyter/IPyhon 中使用:

# Get some test data:
!pip install vega_datasets
from vega_datasets import data
my_cars_df = data.cars()
# Install and use RBQL:
!pip install rbql
%load_ext rbql
%rbql SELECT * FROM my_cars_df WHERE a.Horsepower > 100 ORDER BY a.Weight_in_lbs DESC

在此示例中

my_cars_df
是 Pandas 数据框。

您可以在这个演示 Google Colab notebook 中尝试一下。

© www.soinside.com 2019 - 2024. All rights reserved.