如何使用read_sql_query(pandas dataframes)指示多索引列

时间:2017-04-12 14:37:10

标签: python sql pandas dataframe multi-index

我有一个包含以下列的表:

| Date | ProductId | SubProductId | Value |

我正在尝试从该表中检索数据并将其放入pandas DataFrame中。

我希望DataFrame具有以下结构:

  • index:dates
  • 专栏:产品
  • 子列:子产品
(products)    1              2               ...          
(subproducts) 1    2    3    1    2    3     ...     
date
2015-01-02   val val val   ...
2015-01-03   val val val   ...
2015-01-04   ...  
2015-01-05     
... 

我已经拥有包含产品,子产品和日期的数据框。

我知道我需要使用 MultiIndex ,这是我尝试过的:

query ="SELECT Date, ProductId, SubProductId, Value " \
    " FROM table "\
    " WHERE SubProductId in (1,2,3)"\
    " AND ProductId in (1,2,3)"\
    " AND Date BETWEEN '2015-01-02' AND '2015-01-08' "\
    " GROUP BY Date, ProductId, SubProductId, Value "\
    " ORDER BY Date, ProductId, SubProductId "  



df = pd.read_sql_query(query, conn, index_col=pd.MultiIndex.from_product([df_products['products'].tolist(), df_subproducts['subproducts'].tolist()])

但它不起作用,因为查询返回一个“值”的向量(形状是值为n 1的nb),而我需要一个矩阵(形状:不同日期的nb x(子产品的nb * nb) prodcuts))在数据框中。

如何实现:

  • 直接通过read sql查询?
  • 一旦数据库值插入?,
  • 或通过“trandofrming”数据帧

注意:我使用的是Microsoft SQL Server。

2 个答案:

答案 0 :(得分:2)

IIUC您可以使用unstack()方法:

df = pd.read_sql_query(query, conn, index_col=['Date','ProductID','SubProductId']) \
       .unstack(['ProductID','SubProductId'])

演示:

In [413]: df
Out[413]:
          Date  ProductID  SubProductId  Value
0   2015-01-02          1             1     11
1   2015-01-02          1             2     12
2   2015-01-02          1             3     13
3   2015-01-02          2             1     14
4   2015-01-02          2             2     15
5   2015-01-02          2             3     16
6   2015-01-03          1             1     17
7   2015-01-03          1             2     18
8   2015-01-03          1             3     19
9   2015-01-03          2             1     20
10  2015-01-03          2             2     21

In [414]: df.set_index(['Date','ProductID','SubProductId']).unstack(['ProductID','SubProductId'])
Out[414]:
             Value
ProductID        1                 2
SubProductId     1     2     3     1     2     3
Date
2015-01-02    11.0  12.0  13.0  14.0  15.0  16.0
2015-01-03    17.0  18.0  19.0  20.0  21.0   NaN

答案 1 :(得分:2)

您也可以使用df.pivot_table('Value', 'Date', ['ProductId', 'SubProductId'])

df = pd.DataFrame(dict(
        Date=pd.date_range('2017-03-31', periods=2).repeat(9),
        ProductId=[1, 1, 1, 2, 2, 2, 3, 3, 3] * 2,
        SubProductId=list('abc') * 6,
        Value=np.random.randint(10, size=18)
    ))

print(df)

         Date  ProductId SubProductId  Value
0  2017-03-31          1            a      8
1  2017-03-31          1            b      2
2  2017-03-31          1            c      5
3  2017-03-31          2            a      4
4  2017-03-31          2            b      3
5  2017-03-31          2            c      2
6  2017-03-31          3            a      9
7  2017-03-31          3            b      3
8  2017-03-31          3            c      1
9  2017-04-01          1            a      3
10 2017-04-01          1            b      5
11 2017-04-01          1            c      7
12 2017-04-01          2            a      3
13 2017-04-01          2            b      6
14 2017-04-01          2            c      4
15 2017-04-01          3            a      5
16 2017-04-01          3            b      2
17 2017-04-01          3            c      0

演示

df.pivot_table('Value', 'Date', ['ProductId', 'SubProductId'])

ProductId     1        2        3      
SubProductId  a  b  c  a  b  c  a  b  c
Date                                   
2017-03-31    8  2  5  4  3  2  9  3  1
2017-04-01    3  5  7  3  6  4  5  2  0
{{1}}