Skip to main content
 首页 » 编程设计

python之SQL Server 选择特定的 DataFrame 格式

2025年05月04日15bonelee

我有一个包含日期、标识符和价格列的表格,例如

| Identifier |   Date   | Price | 
|------------|----------|-------| 
|    693477AA|1990/10/31|    100| 
|    353477ZB|1991/08/31|    101| 
|    123457ZB|1992/08/31|    105| 

我正在使用 Pandas read_sql从 SQL Server 数据库中获取数据的函数。无论是使用 SQL 还是 pandas DataFrame 功能,我都需要将数据转换为以下 pandas DataFrame 格式。

           693477AA     353477ZB     123457ZB 
Date            
1988-1-1        NaN          NaN        99.41 
1988-1-2     100.54          NaN        98.11 
1988-1-3      99.45          NaN          NaN  

因此表中的每个 DISTINCT 日期都有一个(可能为 Null)价格条目。对于满足条件的标识符集。

现在我用 for 循环工作,

data = [] 
identifiers = "SELECT DISTINCT Identifier FROM TABLE WHERE [Condition]" 
for id in identifiers: 
    data.append("SELECT Date, Price FROM TABLE WHERE Identifier=[id] ORDER BY DATE") 
pandas.concat(data, axis=1) 

然而,这仅适用于非常严格的 [Condition],因为表非常大(>3M 行)。

我如何实现 SQL、DataFrame 操作或两者的组合来实现所需的格式?

谢谢。

请您参考如下方法:

我们可以使用pivot()功能:

In [144]: df.pivot(index='Date', columns='Identifier', values='Price').rename_axis(None, 1) 
Out[144]: 
            123457ZB  353477ZB  693477AA 
Date 
1990/10/31       NaN       NaN     100.0 
1991/08/31       NaN     101.0       NaN 
1992/08/31     105.0       NaN       NaN 

或DataFrame.unstack() :

In [149]: df.set_index(['Date','Identifier'])['Price'].unstack('Identifier') 
Out[149]: 
Identifier  123457ZB  353477ZB  693477AA 
Date 
1990/10/31       NaN       NaN     100.0 
1991/08/31       NaN     101.0       NaN 
1992/08/31     105.0       NaN       NaN 

或crosstab() :

In [154]: pd.crosstab(index=df['Date'], columns=df['Identifier'],  
                      values=df['Price'], aggfunc='first') \ 
            .rename_axis(None, 1) 
Out[154]: 
            123457ZB  353477ZB  693477AA 
Date 
1990/10/31       NaN       NaN     100.0 
1991/08/31       NaN     101.0       NaN 
1992/08/31     105.0       NaN       NaN 

或pivot_table() :

In [156]: df.pivot_table(index='Date', columns='Identifier', values='Price', fill_value=0).rename_axis(None, 1) 
Out[156]: 
            123457ZB  353477ZB  693477AA 
Date 
1990/10/31         0         0       100 
1991/08/31         0       101         0 
1992/08/31       105         0         0 

请注意,如果您更喜欢在 SQL Server 端“透视”数据 - 请检查 this question