Pandas read_sql 同时使用 index_col 和列参数时复制列

Pandas read_sql duplicating columns when using both index_col and columns parameters

我有一个带有 table test_data 的 SQLite 数据库,其列是:

date id kpi value run_datetime

我正在使用 read_sql 函数读取此 table,仅保留前 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']
)

但是,这 returns 以下内容:

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()

根据 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']
)