Python 透视数据帧并将非轴列作为一个系列获取

Python 透视数据帧并将非轴列作为一个系列获取,python,pandas,Python,Pandas,我使用pandas.io.sql.read_框架从数据库中提取了一个数据集,如下所示 Period Category Projected Actual Previous 0 2013-01 A 1214432.94 3175516.32 3001149.50 1 2013-01 B 624010.78 867729.20 866639.38 2 2013-01 C

我使用pandas.io.sql.read_框架从数据库中提取了一个数据集,如下所示

      Period Category    Projected       Actual     Previous
 0   2013-01 A          1214432.94   3175516.32   3001149.50  
 1   2013-01 B           624010.78    867729.20    866639.38
 2   2013-01 C          2533443.36   2314765.87   2482210.68
 3   2013-01 D          5616228.49   5672648.92   5918737.79
 4   2013-01 E           492184.31   1009281.36    990499.75
 5   2013-01 F         32824689.07  29610034.26  32248832.59
 6   2013-01 G            94192.33    152839.03    189061.80
 7   2013-01 H          1271544.89   1545591.40   1054648.58
 8   2013-01 I          8273369.88   8656894.51   8691683.73
 9   2013-01 J          8540953.73   8012622.14   8671895.07
 10  2013-01 K          8016059.13   8530401.75   9953181.37
 11  2013-01 L          1190095.56    512354.65    459954.82
 12  2013-01 M           850057.11   1077172.22   1097503.89
 13  2013-02 A          1227779.01   2850482.70   3070764.66
 14  2013-02 B           636124.55    822016.04    866802.59
 15  2013-02 C          2581194.49   2471194.78   2681301.30
 16  2013-02 D          5970719.17   5179206.09   5872806.59
 17  2013-02 E           477820.01   1199334.74   1330452.48
 18  2013-02 F         34537100.44  29082997.97  31982248.04
 19  2013-02 G            92523.45     75865.03     93782.83
 ...
<class 'pandas.core.frame.DataFrame'>
Index: 13 entries, A ...
Data columns (total 33 columns):
(Projected, 2013-01)    13  non-null values
(Projected, 2013-02)    13  non-null values
(Projected, 2013-03)    13  non-null values
(Projected, 2013-04)    13  non-null values
(Projected, 2013-05)    13  non-null values
(Projected, 2013-06)    13  non-null values
(Projected, 2013-07)    13  non-null values
(Projected, 2013-08)    13  non-null values
(Projected, 2013-09)    13  non-null values
(Projected, 2013-10)    13  non-null values
(Projected, 2013-11)    12  non-null values
(Actual, 2013-01)       13  non-null values
(Actual, 2013-02)       13  non-null values
(Actual, 2013-03)       13  non-null values
(Actual, 2013-04)       13  non-null values
(Actual, 2013-05)       13  non-null values
(Actual, 2013-06)       13  non-null values
(Actual, 2013-07)       13  non-null values
(Actual, 2013-08)       13  non-null values
(Actual, 2013-09)       13  non-null values
(Actual, 2013-10)       13  non-null values
(Actual, 2013-11)       12  non-null values
(Previous, 2013-01)     13  non-null values
(Previous, 2013-02)     13  non-null values
(Previous, 2013-03)     13  non-null values
(Previous, 2013-04)     13  non-null values
(Previous, 2013-05)     13  non-null values
(Previous, 2013-06)     13  non-null values
(Previous, 2013-07)     13  non-null values
(Previous, 2013-08)     13  non-null values
(Previous, 2013-09)     13  non-null values
(Previous, 2013-10)     13  non-null values
(Previous, 2013-11)     12  non-null values
dtypes: float64(33)     
Period 2013-01 2013-02 2013-03 ...
Group
A       Series  Series  Series ...
B       Series  Series  Series ...
C       Series  Series  Series ...
D       Series  Series  Series ...
...
如果我使用D.pivot\u table(rows=“Category”,cols=“Period”,aggfunc=“sum”)透视表,我会得到一个如下所示的多索引数据帧

      Period Category    Projected       Actual     Previous
 0   2013-01 A          1214432.94   3175516.32   3001149.50  
 1   2013-01 B           624010.78    867729.20    866639.38
 2   2013-01 C          2533443.36   2314765.87   2482210.68
 3   2013-01 D          5616228.49   5672648.92   5918737.79
 4   2013-01 E           492184.31   1009281.36    990499.75
 5   2013-01 F         32824689.07  29610034.26  32248832.59
 6   2013-01 G            94192.33    152839.03    189061.80
 7   2013-01 H          1271544.89   1545591.40   1054648.58
 8   2013-01 I          8273369.88   8656894.51   8691683.73
 9   2013-01 J          8540953.73   8012622.14   8671895.07
 10  2013-01 K          8016059.13   8530401.75   9953181.37
 11  2013-01 L          1190095.56    512354.65    459954.82
 12  2013-01 M           850057.11   1077172.22   1097503.89
 13  2013-02 A          1227779.01   2850482.70   3070764.66
 14  2013-02 B           636124.55    822016.04    866802.59
 15  2013-02 C          2581194.49   2471194.78   2681301.30
 16  2013-02 D          5970719.17   5179206.09   5872806.59
 17  2013-02 E           477820.01   1199334.74   1330452.48
 18  2013-02 F         34537100.44  29082997.97  31982248.04
 19  2013-02 G            92523.45     75865.03     93782.83
 ...
<class 'pandas.core.frame.DataFrame'>
Index: 13 entries, A ...
Data columns (total 33 columns):
(Projected, 2013-01)    13  non-null values
(Projected, 2013-02)    13  non-null values
(Projected, 2013-03)    13  non-null values
(Projected, 2013-04)    13  non-null values
(Projected, 2013-05)    13  non-null values
(Projected, 2013-06)    13  non-null values
(Projected, 2013-07)    13  non-null values
(Projected, 2013-08)    13  non-null values
(Projected, 2013-09)    13  non-null values
(Projected, 2013-10)    13  non-null values
(Projected, 2013-11)    12  non-null values
(Actual, 2013-01)       13  non-null values
(Actual, 2013-02)       13  non-null values
(Actual, 2013-03)       13  non-null values
(Actual, 2013-04)       13  non-null values
(Actual, 2013-05)       13  non-null values
(Actual, 2013-06)       13  non-null values
(Actual, 2013-07)       13  non-null values
(Actual, 2013-08)       13  non-null values
(Actual, 2013-09)       13  non-null values
(Actual, 2013-10)       13  non-null values
(Actual, 2013-11)       12  non-null values
(Previous, 2013-01)     13  non-null values
(Previous, 2013-02)     13  non-null values
(Previous, 2013-03)     13  non-null values
(Previous, 2013-04)     13  non-null values
(Previous, 2013-05)     13  non-null values
(Previous, 2013-06)     13  non-null values
(Previous, 2013-07)     13  non-null values
(Previous, 2013-08)     13  non-null values
(Previous, 2013-09)     13  non-null values
(Previous, 2013-10)     13  non-null values
(Previous, 2013-11)     12  non-null values
dtypes: float64(33)     
Period 2013-01 2013-02 2013-03 ...
Group
A       Series  Series  Series ...
B       Series  Series  Series ...
C       Series  Series  Series ...
D       Series  Series  Series ...
...
其中,每个“系列”是一个由三个数字组成的系列,三个数字分别是(预测值、实际值和以前的)聚合值


我已经研究了pivot表和pandas.core.reforme中melt函数的stack、unstack、各种组合或行、col和values参数,但它们似乎都不是我想要的

我相信您是在向我们展示,而且,作为结果的包含系列的数据集没有实际的适用性

也许您正在寻找groupby对象而不是pivot

>>> df.groupby(["Category", 'Period']).get_group(('A', '2013-01'))
    Period Category   Projected      Actual   Previous
0  2013-01        A  1214432.94  3175516.32  3001149.5
>>> df.groupby(["Category", 'Period']).get_group(('A', '2013-01'))[['Projected', 'Actual', 'Previous']].sum()
Projected    1214432.94
Actual       3175516.32
Previous     3001149.50
dtype: float64

我相信@alko的建议是正确的,在开始时建议使用
groupby
,然后是
sum
。如果您的目标是在每个位置都有一个iterable,那么您可以使用
zip
创建一列元组。这个怎么样:

import pandas as pd
import numpy as np
from itertools import product

np.random.seed(1)

periods = range(0,3)
categories = list('ABC')

rows = list(product(periods, categories)) * 2
n = len(rows)

df = pd.DataFrame({'Projected': np.random.randn(n), 
                   'Actual': np.random.randn(n), 
                   'Previous': np.random.randn(n)},
                  index = pd.MultiIndex.from_tuples(rows))
df.index.names = ['Period', 'Category']
summed = df.groupby(level=['Period', 'Category']).sum()
summed['tuple'] = zip(*[summed[c] for c in ['Projected', 'Actual', 'Previous']])
result = summed['tuple'].unstack('Period')
给予


为了完整起见,你可以回到另一个方向,尽管这有点痛苦:

andback = result.stack().apply(lambda t: pd.Series({'Projected': t[0],
                                              'Actual': t[1],
                                              'Previous': t[2]}))
给予


只是为了在评论中帮助别人。以下是我如何添加小计和总计:

def add_subtotal(g):
    category = g.index.get_level_values('Category')[0]
    g.loc[(category, 'subtotal'), :] = g.sum()
    return g

with_subtotals = andback.groupby(level='Category', axis=0).transform(add_subtotal)

with_subtotals.loc[('Grand', 'Total'), :] = with_subtotals\
    .loc[with_subtotals.index.get_level_values('Period')=='subtotal', :]\
    .sum()
其中:


我需要表格格式的数据,以便通过django模板语言方便地进行遍历,即我希望在行上循环。最后,我希望表中的每个单元格都有三个值,以逗号分隔。因此需要数据透视格式的元组。如果我使用groupby,我基本上必须用python构建表。如果我能让熊猫做到这一点,而不是在蟒蛇,这是非常缓慢的,我会认为实用性。我在这里能做些什么来避免XY问题?@sirlark,看看下面我的答案。我一直在其他一些环境中使用这种解决方案,而且效果很好。如果不尝试几种不同的方法,我永远记不住语法,但基本上,一旦你有了一个系列列表(通过下面的列表插值完成),你就可以
zip(*[list\u of_series])
来创建元组。我一直在寻找一种方法来做到这一点,而不必打断python来形成元组,而且找不到一种方法,看来这是我将要得到的最接近的答案,我会接受这个答案。至少zip不直接涉及python循环,而且对于我的情况,它相当快。很高兴它起到了作用。另一个注意事项:使用数据帧内容中的元组,您可以轻松地将单个列转换为多索引,例如:
df.index=pd.MultiIndex.from_tuples(df['tuple\u column'])
您知道是否可以将小计添加到每个类别(a、B、C)?然后在最后有一个最终的总数?@8one6是“andback”一个。理想情况下,每个类别下都有一个小计,或者如果不可能的话。在周期栏中加上“a总计”、“B总计”、“C总计”,然后再加上“总计”,这应该是一个单独的问题,但我在上面至少提出了一种方法。