多索引数据框到带有新列的数据透视表

Posted

技术标签:

【中文标题】多索引数据框到带有新列的数据透视表【英文标题】:multiindex dataframe to pivot table with a new column 【发布时间】:2016-08-29 20:21:33 【问题描述】:

我有一个带有多索引的数据框,我想将其转换为数据透视表,对列进行汇总,数据为:

import random
import pandas as pd
arrays = [[2,2,3,3,3,4,4,4,4,5,5,7,7],
      [1,2,1,2,3,1,2,3,4,1,3,1,4]]
tuples = list(zip(*arrays))
index = pd.MultiIndex.from_tuples(tuples, names = ['first','second'])
data = pd.Series(random.sample(range(1,100),13), index = index)
data

first  second
2      1         28
       2         20
3      1          7
       2          6
       3         86
4      1         10
       2         30
       3          8
       4         44
5      1         74
       3         65
7      1         12
       4         72
dtype: int64

我想将其转换为(内部值是列值的总和):

      second==1    second > 1
first
2      28          20
3      7           92
4      10          38
5      74          65
7      1           72

有没有一种优雅的方式来做到这一点?

谢谢!

【问题讨论】:

【参考方案1】:

设置

import random
import pandas as pd
random.seed(314)

arrays = [[2,2,3,3,3,4,4,4,4,5,5,7,7],
      [1,2,1,2,3,1,2,3,4,1,3,1,4]]
tuples = list(zip(*arrays))
index = pd.MultiIndex.from_tuples(tuples, names = ['first','second'])
data = pd.Series(random.sample(range(1,100),13), index = index)
data

first  second
2      1         20
       2         12
3      1          1
       2         63
       3         24
4      1         21
       2         55
       3         45
       4         18
5      1         11
       3         25
7      1          3
       4         26
dtype: int64

解决方案

def eq_one(x):
    values = [x.ix[1], x.sum() - x.ix[1]]
    index = ['second==1', 'second > 1']
    return pd.Series(values, index=index)

data.unstack().apply(eq_one, axis=1)

       second==1  second > 1
first                       
2           20.0        12.0
3            1.0        87.0
4           21.0       118.0
5           11.0        25.0
7            3.0        26.0

【讨论】:

我使用了data.unstack().fillna(0).apply(eq_one, axis=1),否则,我在转换后的表中有NaN。【参考方案2】:

修改您的特定级别索引并使用groupby 重组数据。 set_levels()get_level_values() 在您修改 pandas multiIndex 的特定级别索引时很有用。

data.index = data.index.set_levels(data.index.get_level_values(1).map(lambda x: 'second = 1' if x == 1 else 'second > 1'), level=1)
print data.unstack().fillna(0).groupby(axis=1, level=0).sum()

second  second = 1  second > 1
first                         
2             44.0        46.0
3            110.0        31.0
4             63.0       150.0
5             74.0         0.0
7              7.0        86.0

【讨论】:

以上是关于多索引数据框到带有新列的数据透视表的主要内容,如果未能解决你的问题,请参考以下文章

排序数据透视表(多索引)

具有多索引的 Pandas 数据透视表小计

对多索引数据透视表 pandas 进行排序

如何合并熊猫数据透视表中的多索引层?

结合 pandas 数据透视表多索引标题 - 一个时间戳,一个字符串

pandas:如何使用多索引运行数据透视?