具有多索引的 Pandas 样式对象

Posted

技术标签:

【中文标题】具有多索引的 Pandas 样式对象【英文标题】:Pandas style object with multi-index 【发布时间】:2017-06-03 22:31:40 【问题描述】:

我正在使用 styler 格式化 pandas 数据框以突出显示列和格式化数字。我也想应用多索引更清晰,愉快和易于阅读。由于我将 Styler 应用于列的子集,因此它不适用于多索引。

例子:

arrays = [np.hstack([['One']*2, ['Two']*2]) , ['A', 'B', 'C', 'D']]
columns = pd.MultiIndex.from_arrays(arrays)
data =  pd.DataFrame(np.random.randn(5, 4), columns=list('ABCD'))
data.columns = columns 
import seaborn as sns
cm = sns.light_palette("green", as_cmap=True)
data.style.background_gradient(cmap=cm, subset=['A'])

有没有办法对列进行子集化,以便样式器可以工作。根据以下来源,这是实现的,但没有示例,所以我很难理解如何应用它: http://pandas.pydata.org/pandas-docs/stable/generated/pandas.formats.style.Styler.html https://github.com/pandas-dev/pandas/issues/11655

谢谢!

【问题讨论】:

【参考方案1】:

我认为你可以使用pd.IndexSlice[...] 方法:

data.style.background_gradient(cmap=cm, subset=pd.IndexSlice[:, pd.IndexSlice[:, 'A']])

演示:

In [5]: data.loc[pd.IndexSlice[:, pd.IndexSlice[:, 'A']]]
Out[5]:
        One
          A
0 -0.808483
1  0.009371
2  0.977138
3 -0.875554
4 -0.052424

In [6]: data
Out[6]:
        One                 Two
          A         B         C         D
0 -0.808483 -2.280683  0.576145  0.649688
1  0.009371  0.721510  1.013764 -0.157493
2  0.977138  1.441392  1.718618 -0.320826
3 -0.875554 -1.060507  1.457075  0.570195
4 -0.052424 -0.742842 -0.203830 -1.202091

在 Jupyter 中:

【讨论】:

非常感谢!我自学了如何分割多指数。我在 pandas 中忽略了一些东西。 我在 Pandas 0.24.2 上收到 TypeError: unhashable type: slice :( @krubo,对于 same 数据集,您是否收到此错误? 是的,我有 import pandas as pd 然后是 import numpy as np 然后是 OP 的代码(最后一行除外),然后是你的答案行,我得到了错误。同时,cabbagetreecustard 的答案工作正常,但使我的代码混乱,因为我不提前知道层次结构。 我可以知道如何在单元格周围制作框架吗?其他人的回答没有显示那些框架【参考方案2】:

如果您知道索引的层次结构是什么,例如“A”在“One”下,您可以使用元组来引用该列。

data.style.background_gradient(cmap=cm, subset=[('One','A')])

然后表格会如上所示。

如果您想用多索引设置多个列的样式,您需要提供一个元组列表,即

arrays = [np.hstack([['One']*2, ['Two']*2]) , ['A', 'B', 'C', 'D']]
columns = pd.MultiIndex.from_arrays(arrays)
data =  pd.DataFrame(np.random.randn(5, 4), columns=list('ABCD'))
data.columns = columns 
cm = sns.light_palette("green", as_cmap=True)
data.style.background_gradient(cmap=cm, subset=[('One','A'),('Two','C')])

这样显示

【讨论】:

【参考方案3】:

这里是另一种方式:

data.style.background_gradient(cmap=cm, subset=data.columns.get_loc_level('A', level=1)[0])

输出:

【讨论】:

是的,这适用于我在 Pandas 0.24.2 和 Python 3.6.8 上。谢谢!【参考方案4】:

对于原始问题:

data.style.background_gradient(cmap=cm,
                               subset=[c for c in data.columns if c[1] == 'A'])

您可以检查一些条件,例如子字符串:

data.style.background_gradient(cmap=cm,
                               subset=[c for c in data.columns if 'T' in c[0]])

或者传递一个子列列表:

data.style.background_gradient(cmap=cm, 
                               subset=[c for c in data.columns if c[1] in ('A', 'C')])

【讨论】:

以上是关于具有多索引的 Pandas 样式对象的主要内容,如果未能解决你的问题,请参考以下文章

具有可迭代对象的字典字典到具有多索引的可迭代对象索引的熊猫数据框

Pandas:具有多索引的 fillna() 方法 - NaN 填充了错误的列

具有多索引的 Pandas 子数据透视表和总数据透视表

如何将 2 个未对齐的 Pandas 系列相乘并接收具有多索引的产品系列

如何在不合并索引的情况下连接具有不同多索引的两个数据帧?

带有多索引的 df.at 与 df.loc