【问题标题】:unpacking a sql select into a pandas dataframe将 sql 选择解压缩到 pandas 数据框中
【发布时间】:2013-06-13 21:53:56
【问题描述】:

假设我有一个大致像这样的选择:

select instrument, price, date from my_prices;

如何将返回的价格解压缩到单个数据框中,其中包含每种工具的系列并按日期编制索引?

明确一点:我正在寻找:

<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: ...
Data columns (total 2 columns):
inst_1    ...
inst_2    ...
dtypes: float64(1), object(1) 

我不是在寻找:

<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: ...
Data columns (total 2 columns):
instrument    ...
price         ...
dtypes: float64(1), object(1)

...这很容易;-)

【问题讨论】:

    标签: python sql pandas


    【解决方案1】:

    您可以将光标对象传递给 DataFrame 构造函数。对于 postgres:

    import psycopg2
    conn = psycopg2.connect("dbname='db' user='user' host='host' password='pass'")
    cur = conn.cursor()
    cur.execute("select instrument, price, date from my_prices")
    df = DataFrame(cur.fetchall(), columns=['instrument', 'price', 'date'])
    

    然后设置索引像

    df.set_index('date', drop=False)
    

    或直接:

    df.index =  df['date']
    

    【讨论】:

    • 你试过read_framepsycopg 吗?开发团队将非常感谢任何有关这是否有效的反馈。谢谢!
    • # 提取列名使得columns=columns: columns = [elt[0] for elt in cur.description]
    • 这是我说的我明确没有寻找的东西,这里没有支点。
    • 我用这种方式动态检索列:df = pd.DataFrame(cur.fetchall(), columns=[desc[0] for desc in cur.description])
    • 感谢您的回答。有没有比手动输入更好的方法来填写列名?
    【解决方案2】:

    更新:最近的熊猫有以下功能:read_sql_tableread_sql_query

    首先创建一个db引擎(这里也可以建立一个连接):

    from sqlalchemy import create_engine
    # see sqlalchemy docs for how to write this url for your database type:
    engine = create_engine('mysql://scott:tiger@localhost/foo')
    

    sqlalchemy database urls

    pandas_read_sql_table

    table_name = 'my_prices'
    df = pd.read_sql_table(table_name, engine)
    

    pandas_read_sql_query

    df = pd.read_sql_query("SELECT instrument, price, date FROM my_prices;", engine)
    

    旧答案引用了已弃用的 read_frame(有关该答案,请参阅此问题的 version history)。


    首先阅读通常是有意义的,然后然后根据您的要求执行转换(因为这些通常在 pandas 中是高效且可读的)。在您的示例中,您可以pivot 结果:

    df.reset_index().pivot('date', 'instrument', 'price')
    

    注意:您可能会错过在 read_frame 中未指定 index_colreset_index

    【讨论】:

    • 哦,就像快捷方式一样。不知道这件事。你知道这是否适用于 psycopg 连接器?
    • 我认为应该可以,您只需使用它设置连接 (con),如果可以,请告诉我! :)
    • +1 想知道这是否适合您。 read_frame/write_frame 的开发人员都不是 postgresql 的普通用户,所以我们没有介绍它。如果遇到问题,请file an issue
    • 这是否已被 pandas.io.sql.read_sql 取代?尝试在 pandas >= 0.18 中导入 read_frame 时出现 importError,而当前文档提到 read_sql。
    • @emunsing 绝对是。还有read_sql_table,应该强烈推荐。
    【解决方案3】:

    这通过远程 postgresql 与 postgres 和 pandas 连接

    # CONNECT TO POSTGRES USING PANDAS
    import psycopg2 as pg
    import pandas.io.sql as psql
    

    这用于与postgres db建立连接

    connection = pg.connect("host=192.168.0.1 dbname=db user=postgres")
    

    这用于从 postgres db 中读取表

    dataframe = psql.read_sql("SELECT * FROM DB.Table", connection)
    

    【讨论】:

    • 感谢您提供此代码 sn-p,它可能会提供一些有限的即时帮助。 proper explanation would greatly improve its long-term value 通过展示为什么这是一个很好的解决问题的方法,并且会使其对未来有其他类似问题的读者更有用。请edit您的回答添加一些解释,包括您所做的假设。
    • 这就是我在问题中明确表示不想做的事情。
    • 是的....当然..因为我是python的初学者..会在那里做更多的解释...
    【解决方案4】:
    import pandas as pd
    import pandas.io.sql as sqlio
    import psycopg2
    
    conn = psycopg2.connect("host='{}' port={} dbname='{}' user={} password={}".format(host, port, dbname, username, pwd))
    sql = "select count(*) from table;"
    dat = sqlio.read_sql_query(sql, conn)
    conn = None
    

    import pandas as pd
    
    conn = psycopg2.connect("host='{}' port={} dbname='{}' user={} password={}".format(host, port, dbname, username, pwd))
    sql = "select count(*) from table;"
    dat = pd.read_sql_query(sql, conn)
    conn = None
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-05-04
      • 1970-01-01
      • 2021-09-27
      • 1970-01-01
      • 2021-07-10
      • 2020-12-12
      • 2016-03-22
      • 2021-05-30
      相关资源
      最近更新 更多