我有一个包含日期、标识符和价格列的表格,例如
| 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
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
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
关于python - SQL Server 选择特定的 DataFrame 格式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45494471/