【问题标题】:Pandas read_sql duplicating columns when using both index_col and columns parametersPandas read_sql在同时使用index_col和columns参数时复制列
【发布时间】:2021-08-15 11:39:19
【问题描述】:

我有一个 SQLite 数据库,其中包含表 test_data,其列是:

date id kpi value run_datetime

我正在使用read_sql 函数读取此表,只保留前4 列,并将前3 列设置为索引。为此,我通过以下方式调用了read_sql 函数:

conn = sqlalchemy.create_engine('sqlite:///test.db')
data = pd.read_sql(
    sql='test_data',
    con=conn,
    columns=['date', 'id', 'kpi', 'value'],
    index_col=['date', 'id', 'kpi']
)

但是,这会返回以下内容:

date__1 id__1 kpi__1 value
date id kpi
2021-05-01 0001 kpi_1 2021-05-01 0001 kpi_1 100
kpi_2 2021-05-01 0001 kpi_2 200
kpi_3 2021-05-01 0001 kpi_3 300

这保留了我想要的列,但它在索引中复制了我想要的 3,而不是像我期望的那样将它们转换为索引。如果我明确使用 read_sql_table 函数,我会得到相同的输出。

所以,我的问题是……

  • 这是意料之中的行为,还是我的查询格式不正确?
  • 如果这是格式错误的查询,我该如何解决?

我可以通过仅使用其中一个参数并在 DataFrame 本身上应用另一个参数的逻辑(例如,仅保留列然后调用 set_index 方法)或通过显式编写 SELECT 查询来解决此问题,所以我要求替代解决方案。


MWE

import pandas as pd
import sqlalchemy


def make_data(connection):
    pd.DataFrame(
        data=[
            ['2021-05-01', '0001', 'kpi_1', 100,  '2021-05-01 09:00'],
            ['2021-05-01', '0001', 'kpi_2', 200,  '2021-05-01 09:00'],
            ['2021-05-01', '0001', 'kpi_3', 300,  '2021-05-01 09:00']
        ],
        columns=['date', 'id', 'kpi', 'value', 'run_datetime']
    ).to_sql(
        name='test_data',
        con=connection,
        if_exists='replace',
        index=False
    )


def main():
    conn = sqlalchemy.create_engine('sqlite:///test.db')
    make_data(conn)

    data = pd.read_sql(
        sql='test_data',
        con=conn,
        columns=['date', 'id', 'kpi', 'value'],
        index_col=['date', 'id', 'kpi']
    )
    print(data)


if __name__ == '__main__':
    main()

【问题讨论】:

  • 但是你想要的结果是什么?假设您希望 3 列的索引和“值”是唯一的实际列,为什么不直接使用 columns=["value"],。索引列将被正确查询。
  • @van 已经解决了,谢谢!我记得columns 指定了 database 中应该保留的列,而不是 DataFrame 中的列,并且index_cols 将重复这些列应该在索引中。

标签: python pandas sqlalchemy


【解决方案1】:

根据 van 的评论,这是一个格式错误的查询 - 索引 (index_col) 的列应该与 DataFrame (columns) 的列不同,因此工作查询是

conn = sqlalchemy.create_engine('sqlite:///test.db')
data = pd.read_sql(
    sql='test_data',
    con=conn,
    columns=['value'],
    index_col=['date', 'id', 'kpi']
)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-09
    • 2014-08-16
    • 2020-03-26
    • 1970-01-01
    • 2016-03-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多