Style

原文:http://pandas.pydata.org/pandas-docs/stable/style.html

译者:飞龙 UsyiyiCN

校对:(虚位以待)

版本0.17.1中的新功能

临时:这是一个新功能,仍在开发中。我们将添加功能,并可能在未来的版本中进行突破性更改。我们很乐意听取您的反馈。 t>

本文档是作为Jupyter Notebook编写的,可以在此处查看或下载

您可以使用DataFrame.style属性,应用条件格式(根据数据内部的数据确定DataFrame的视觉样式)。这是一个返回pandas.Styler对象的属性,它具有用于格式化和显示DataFrames的有用方法。

样式是使用CSS完成的。您可以编写取得标量DataFrame系列的“样式函数”,并返回like-indexed DataFrames或Series with CSS 属性:值“对。这些函数可以递增地传递到样式器,样式器在渲染之前收集样式。

Contents

Building Styles

将您的样式函数传递到以下方法之一:

  • Styler.applymap:elementwise
  • Styler.apply:column- / row- / table-wise

这两个方法都有一个函数(和一些其他关键字参数),并以某种方式将你的函数应用到DataFrame。Styler.applymap按元素方式处理DataFrame。Styler.apply根据axis关键字参数,将每个列或行一次性传递到您的DataFrame或整个表格。对于逐列使用axis = 0,按行使用axis = 1,并且对于整个表立即使用axis = None

对于Styler.applymap,您的函数应采用标量,并返回一个具有CSS属性值对的字符串。

对于Styler.apply,您的函数应采用Series或DataFrame(取决于轴参数),并返回具有相同形状的Series或DataFrame,其中每个值都是具有CSS属性值对的字符串。

让我们看一些例子。

在[1]:
import pandas as pd
import numpy as np

np.random.seed(24)
df = pd.DataFrame({'A': np.linspace(1, 10, 10)})
df = pd.concat([df, pd.DataFrame(np.random.randn(10, 4), columns=list('BCDE'))],
               axis=1)
df.iloc[0, 2] = np.nan

这里是一个无聊的例子,渲染一个DataFrame,没有任何(可见)样式:

在[2]:
df.style
Out [2]:
一个BCDE
0 1 1.32921 -0.31628-0.99081
1 2 -1.07082-1.43871 0.564417 0.295722
2 3 -1.6264 0.219565 0.678805 1.88927
3 4 0.961538 0.104011 -0.481165 0.850229
4 5 1.45342 1.05774 0.165562 0.515018
5 6 -1.33694 0.562861 1.39285 -0.063328
6 7 0.121668 1.2076 -0.00204021 1.6278
7 8 0.354493 1.03753 -0.385684 0.519818
8 9 1.68658 -1.32596 1.42898 -2.08935
9 10 -0.12982 0.631523 -0.586538 0.29072

注意DataFrame.style属性是返回Styler对象的propetry。样式器具有定义的_repr_html _方法,因此它们会自动呈现。如果你想要实际的HTML返回进一步处理或写入文件调用.render()方法返回一个字符串。

上面的输出看起来非常类似于标准的DataFrame HTML表示。但是我们在幕后做了一些工作,将CSS类附加到每个单元格。我们可以通过调用.render方法查看这些。

在[3]:
df.style.highlight_null().render().split('\n')[:10]
出[3]:
[u'',
 u'        <style  type="text/css" >',
 u'        ',
 u'        ',
 u'            #T_bc5e3090_c9fe_11e6_8f44_778134d549ffrow0_col2 {',
 u'            ',
 u'                background-color:  red;',
 u'            ',
 u'            }',
 u'        ']

row0_col2是特定单元格的标识符。我们还为每个行/列标识符添加了每个DataFrame唯一的UUID,以便一个样式不会与同一笔记本或页面中另一个样式发生冲突(您可以设置uuid t0 >如果你想把两个DataFrames的样式绑在一起)。

在编写样式函数时,您需要处理生成所需的CSS属性/值对。Pandas匹配那些标识每个单元格的CSS类。

让我们写一个简单的样式函数,将负数红色和正数黑色。

在[4]:
def color_negative_red(val):
    """
    Takes a scalar and returns a string with
    the css property `'color: red'` for negative
    strings, black otherwise.
    """
    color = 'red' if val < 0 else 'black'
    return 'color: %s' % color

在这种情况下,单元格的样式仅取决于它自己的值。这意味着我们应该使用元素方式工作的Styler.applymap方法。

在[5]:
s = df.style.applymap(color_negative_red)
s
出[5]:
一个BCDE
0 1 1.32921 -0.31628-0.99081
1 2 -1.07082-1.43871 0.564417 0.295722
2 3 -1.6264 0.219565 0.678805 1.88927
3 4 0.961538 0.104011 -0.481165 0.850229
4 5 1.45342 1.05774 0.165562 0.515018
5 6 -1.33694 0.562861 1.39285 -0.063328
6 7 0.121668 1.2076 -0.00204021 1.6278
7 8 0.354493 1.03753 -0.385684 0.519818
8 9 1.68658 -1.32596 1.42898 -2.08935
9 10 -0.12982 0.631523 -0.586538 0.29072

注意与标准df.applymap的相似性,它在元素方面对DataFrames进行操作。我们希望您能够重新使用您现有的如何与DataFrames交互的知识。

还要注意,我们的函数返回一个包含CSS属性和值的字符串,用冒号分隔,就像在&lt; style&gt;标签中。这将是一个共同的主题。

最后,输入形状匹配。Styler.applymap在每个标量输入上调用函数,函数返回标量输出。

现在假设您想突出显示每列中的最大值。我们不能使用.applymap,因为它是按元素操作的。相反,我们将转到.apply,它按列方式操作(或使用关键字按行操作)。稍后我们会看到highlight_max已在Styler上定义,因此您不需要自己编写。

在[6]:
def highlight_max(s):
    '''
    highlight the maximum in a Series yellow.
    '''
    is_max = s == s.max()
    return ['background-color: yellow' if v else '' for v in is_max]
在[7]:
df.style.apply(highlight_max)
出[7]:
一个BCDE
0 1 1.32921 -0.31628-0.99081
1 2 -1.07082-1.43871 0.564417 0.295722
2 3 -1.6264 0.219565 0.678805 1.88927
3 4 0.961538 0.104011 -0.481165 0.850229
4 5 1.45342 1.05774 0.165562 0.515018
5 6 -1.33694 0.562861 1.39285 -0.063328
6 7 0.121668 1.2076 -0.00204021 1.6278
7 8 0.354493 1.03753 -0.385684 0.519818
8 9 1.68658 -1.32596 1.42898 -2.08935
9 10 -0.12982 0.631523 -0.586538 0.29072

在这种情况下,输入为Series,一次一列。请注意,highlight_max的输出形状与输入形状匹配,即具有len(s)项的数组。

我们鼓励您使用方法链在分段式构建样式,最后在链的末尾呈现。

在[8]:
df.style.\
    applymap(color_negative_red).\
    apply(highlight_max)
Out [8]:
一个BCDE
0 1 1.32921 -0.31628-0.99081
1 2 -1.07082-1.43871 0.564417 0.295722
2 3 -1.6264 0.219565 0.678805 1.88927
3 4 0.961538 0.104011 -0.481165 0.850229
4 5 1.45342 1.05774 0.165562 0.515018
5 6 -1.33694 0.562861 1.39285 -0.063328
6 7 0.121668 1.2076 -0.00204021 1.6278
7 8 0.354493 1.03753 -0.385684 0.519818
8 9 1.68658 -1.32596 1.42898 -2.08935
9 10 -0.12982 0.631523 -0.586538 0.29072

上面我们使用Styler.apply每次传递一列一个。

*Debugging Tip*: If you're having trouble writing your style function, try just passing it into DataFrame.apply. 在内部,Styler.apply使用DataFrame.apply,因此结果应该相同。

如果您想突出显示整个表中的最大值,该怎么办?使用.apply(function,axis = None)来表示您的函数需要整个表,而不是一次一列或一行。让我们试试下。

我们将改写highlight-max来处理Series(从.apply(axis = 0或1))或DataFrames(从.apply无))。我们还将允许颜色可调,以演示.apply.applymap传递关键字参数。

在[9]:
def highlight_max(data, color='yellow'):
    '''
    highlight the maximum in a Series or DataFrame
    '''
    attr = 'background-color: {}'.format(color)
    if data.ndim == 1:  # Series from .apply(axis=0) or axis=1
        is_max = data == data.max()
        return [attr if v else '' for v in is_max]
    else:  # from .apply(axis=None)
        is_max = data == data.max().max()
        return pd.DataFrame(np.where(is_max, attr, ''),
                            index=data.index, columns=data.columns)

当使用Styler.apply(func,axis = None)时,函数必须返回具有相同索引和列标签的DataFrame。

在[10]:
df.style.apply(highlight_max, color='darkorange', axis=None)
出[10]:
一个BCDE
0 1 1.32921 -0.31628-0.99081
1 2 -1.07082-1.43871 0.564417 0.295722
2 3 -1.6264 0.219565 0.678805 1.88927
3 4 0.961538 0.104011 -0.481165 0.850229
4 5 1.45342 1.05774 0.165562 0.515018
5 6 -1.33694 0.562861 1.39285 -0.063328
6 7 0.121668 1.2076 -0.00204021 1.6278
7 8 0.354493 1.03753 -0.385684 0.519818
8 9 1.68658 -1.32596 1.42898 -2.08935
9 10 -0.12982 0.631523 -0.586538 0.29072

Building Styles Summary

样式函数应返回带有一个或多个CSS 属性的字符串:value以分号分隔。使用

  • Styler.applymap(func)用于元素样式
  • Styler.apply(func,axis = 0)用于列方式
  • Styler.apply(func,axis = 1)用于行式样式
  • Styler.apply(func,axis = None)用于表格样式

至关重要的是,func的输入和输出形状必须匹配。如果x是输入,则func(x).shape == x.shape

Finer Control: Slicing

Styler.applyStyler.applymap都接受子集关键字。这样,您就可以将样式应用于特定的行或列,而无需将该逻辑编写到样式函数中。

传递给子集的值与切分DataFrame类似。

  • 标量被视为列标签
  • 列表(或系列或numpy数组)
  • 元组被视为(row_indexer,column_indexer)

考虑使用pd.IndexSlice来构造最后一个的元组。

在[11]:
df.style.apply(highlight_max, subset=['B', 'C', 'D'])
Out [11]:
一个BCDE
0 1 1.32921 -0.31628-0.99081
1 2 -1.07082-1.43871 0.564417 0.295722
2 3 -1.6264 0.219565 0.678805 1.88927
3 4 0.961538 0.104011 -0.481165 0.850229
4 5 1.45342 1.05774 0.165562 0.515018
5 6 -1.33694 0.562861 1.39285 -0.063328
6 7 0.121668 1.2076 -0.00204021 1.6278
7 8 0.354493 1.03753 -0.385684 0.519818
8 9 1.68658 -1.32596 1.42898 -2.08935
9 10 -0.12982 0.631523 -0.586538 0.29072

对于行和列切片,.loc的任何有效索引器将工作。

在[12]:
df.style.applymap(color_negative_red,
                  subset=pd.IndexSlice[2:5, ['B', 'D']])
Out [12]:
一个BCDE
0 1 1.32921 -0.31628-0.99081
1 2 -1.07082-1.43871 0.564417 0.295722
2 3 -1.6264 0.219565 0.678805 1.88927
3 4 0.961538 0.104011 -0.481165 0.850229
4 5 1.45342 1.05774 0.165562 0.515018
5 6 -1.33694 0.562861 1.39285 -0.063328
6 7 0.121668 1.2076 -0.00204021 1.6278
7 8 0.354493 1.03753 -0.385684 0.519818
8 9 1.68658 -1.32596 1.42898 -2.08935
9 10 -0.12982 0.631523 -0.586538 0.29072

现在只支持基于标签的切片,而不是位置。

如果您的样式函数使用子集关键字参数,请考虑在functools.partial中包装函数,以分离出该关键字。

my_func2 = functools.partial(my_func, subset=42)

Finer Control: Display Values

我们在样式器中区分显示值与实际值。要控制显示值,请在每个单元格中打印文本,使用Styler.format单元格可以根据格式规范字符串或一个可调用,它接受一个单一的值并返回一个字符串。

在[13]:
df.style.format("{:.2%}")
出[13]:
一个BCDE
0 100.00%132.92%纳米%-31.63%-99.08%
1 200.00%-107.08%-143.87%56.44%29.57%
2 300.00%-162.64%21.96%67.88%188.93%
3 400.00%96.15%10.40%-48.12%85.02%
4 500.00%145.34%105.77%16.56%51.50%
5 600.00%-133.69%56.29%139.29%-6.33%
6 700.00%12.17%120.76%-0.20%162.78%
7 800.00%35.45%103.75%-38.57%51.98%
8 900.00%168.66%-132.60%142.90%-208.94%
9 1000.00%-12.98%63.15%-58.65%29.07%

使用字典格式化特定列。

在[14]:
df.style.format({'B': "{:0<4.0f}", 'D': '{:+.2f}'})
Out [14]:
一个BCDE
0 1 1000 -0.32-0.99081
1 2 -100-1.43871+0.56 0.295722
2 3 -200 0.219565 +0.68 1.88927
3 4 1000 0.104011 -0.48 0.850229
4 5 1000 1.05774 +0.17 0.515018
5 6 -100 0.562861 +1.39-0.063328
6 7 0000 1.2076 -0.00 1.6278
7 8 0000 1.03753 -0.39 0.519818
8 9 2000 -1.32596+1.43-2.08935
9 10 -000 0.631523 -0.59 0.29072

或者传递一个callable(或callables的字典)以更灵活的处理。

在[15]:
df.style.format({"B": lambda x: {:.2f}".format(abs(x))})
---------------------------------------------------------------------------
UnicodeDecodeError                        Traceback (most recent call last)
/home/joris/miniconda3/envs/docs/lib/python2.7/site-packages/IPython/core/formatters.pyc in __call__(self, obj)
    309             method = get_real_method(obj, self.print_method)
    310             if method is not None:
--> 311                 return method()
    312             return None
    313         else:

/home/joris/scipy/pandas/pandas/formats/style.py in _repr_html_(self)
    190     def _repr_html_(self):
    191         """Hooks into Jupyter notebook rich display system."""
--> 192         return self.render()
    193 
    194     def _translate(self):

/home/joris/scipy/pandas/pandas/formats/style.py in render(self)
    423                    if any(any(y) for y in x['props'])]
    424         d['cellstyle'] = trimmed
--> 425         return self.template.render(**d)
    426 
    427     def _update_ctx(self, attrs):

/home/joris/miniconda3/envs/docs/lib/python2.7/site-packages/jinja2/environment.pyc in render(self, *args, **kwargs)
    987         except Exception:
    988             exc_info = sys.exc_info()
--> 989         return self.environment.handle_exception(exc_info, True)
    990 
    991     def stream(self, *args, **kwargs):

/home/joris/miniconda3/envs/docs/lib/python2.7/site-packages/jinja2/environment.pyc in handle_exception(self, exc_info, rendered, source_hint)
    752             self.exception_handler(traceback)
    753         exc_type, exc_value, tb = traceback.standard_exc_info
--> 754         reraise(exc_type, exc_value, tb)
    755 
    756     def join_path(self, template, parent):

<template> in top-level template code()

UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position 0: ordinal not in range(128)
Out [15]:
<pandas.formats.style.Styler at 0x7fa8ba59bf50>

Builtin Styles

最后,我们期望某些样式函数是公用的,因为我们已经在Styler中包含了一些“内置”,所以你不必自己编写它们。

在[16]:
df.style.highlight_null(null_color='red')
Out [16]:
一个BCDE
0 1 1.32921 -0.31628-0.99081
1 2 -1.07082-1.43871 0.564417 0.295722
2 3 -1.6264 0.219565 0.678805 1.88927
3 4 0.961538 0.104011 -0.481165 0.850229
4 5 1.45342 1.05774 0.165562 0.515018
5 6 -1.33694 0.562861 1.39285 -0.063328
6 7 0.121668 1.2076 -0.00204021 1.6278
7 8 0.354493 1.03753 -0.385684 0.519818
8 9 1.68658 -1.32596 1.42898 -2.08935
9 10 -0.12982 0.631523 -0.586538 0.29072

您可以使用background_gradient方法创建“热图”。这些需要matplotlib,我们将使用Seaborn来获得一个很好的色彩映射。

在[17]:
import seaborn as sns

cm = sns.light_palette("green", as_cmap=True)

s = df.style.background_gradient(cmap=cm)
s
/home/joris/miniconda3/envs/docs/lib/python2.7/site-packages/IPython/html.py:14: ShimWarning: The `IPython.html` package has been deprecated. You should import from `notebook` instead. `IPython.html.widgets` has moved to `ipywidgets`.
  "`IPython.html.widgets` has moved to `ipywidgets`.", ShimWarning)
/home/joris/miniconda3/envs/docs/lib/python2.7/site-packages/matplotlib/colors.py:581: RuntimeWarning: invalid value encountered in less
  cbook._putmask(xa, xa < 0.0, -1)
Out [17]:
一个BCDE
0 1 1.32921 -0.31628-0.99081
1 2 -1.07082-1.43871 0.564417 0.295722
2 3 -1.6264 0.219565 0.678805 1.88927
3 4 0.961538 0.104011 -0.481165 0.850229
4 5 1.45342 1.05774 0.165562 0.515018
5 6 -1.33694 0.562861 1.39285 -0.063328
6 7 0.121668 1.2076 -0.00204021 1.6278
7 8 0.354493 1.03753 -0.385684 0.519818
8 9 1.68658 -1.32596 1.42898 -2.08935
9 10 -0.12982 0.631523 -0.586538 0.29072

Styler.background_gradient使用关键字参数粗略地说,这些扩展了高 t>百分比的数据范围,以便在我们转换颜色时,不使用色彩映射的整个范围。这是有用的,这样你可以读取文本仍然。

在[18]:
# Uses the full color range
df.loc[:4].style.background_gradient(cmap='viridis')
出[18]:
一个BCDE
0 1 1.32921 -0.31628-0.99081
1 2 -1.07082-1.43871 0.564417 0.295722
2 3 -1.6264 0.219565 0.678805 1.88927
3 4 0.961538 0.104011 -0.481165 0.850229
4 5 1.45342 1.05774 0.165562 0.515018
在[19]:
# Compreess the color range
(df.loc[:4]
    .style
    .background_gradient(cmap='viridis', low=.5, high=0)
    .highlight_null('red'))
出[19]:
一个BCDE
0 1 1.32921 -0.31628-0.99081
1 2 -1.07082-1.43871 0.564417 0.295722
2 3 -1.6264 0.219565 0.678805 1.88927
3 4 0.961538 0.104011 -0.481165 0.850229
4 5 1.45342 1.05774 0.165562 0.515018

您可以在DataFrame中包括“条形图”。

在[20]:
df.style.bar(subset=['A', 'B'], color='#d65f5f')
Out [20]:
一个BCDE
0 1 1.32921 -0.31628-0.99081
1 2 -1.07082-1.43871 0.564417 0.295722
2 3 -1.6264 0.219565 0.678805 1.88927
3 4 0.961538 0.104011 -0.481165 0.850229
4 5 1.45342 1.05774 0.165562 0.515018
5 6 -1.33694 0.562861 1.39285 -0.063328
6 7 0.121668 1.2076 -0.00204021 1.6278
7 8 0.354493 1.03753 -0.385684 0.519818
8 9 1.68658 -1.32596 1.42898 -2.08935
9 10 -0.12982 0.631523 -0.586538 0.29072

还有.highlight_min.highlight_max

在[21]:
df.style.highlight_max(axis=0)
出[21]:
一个BCDE
0 1 1.32921 -0.31628-0.99081
1 2 -1.07082-1.43871 0.564417 0.295722
2 3 -1.6264 0.219565 0.678805 1.88927
3 4 0.961538 0.104011 -0.481165 0.850229
4 5 1.45342 1.05774 0.165562 0.515018
5 6 -1.33694 0.562861 1.39285 -0.063328
6 7 0.121668 1.2076 -0.00204021 1.6278
7 8 0.354493 1.03753 -0.385684 0.519818
8 9 1.68658 -1.32596 1.42898 -2.08935
9 10 -0.12982 0.631523 -0.586538 0.29072
在[22]:
df.style.highlight_min(axis=0)
出[22]:
一个BCDE
0 1 1.32921 -0.31628-0.99081
1 2 -1.07082-1.43871 0.564417 0.295722
2 3 -1.6264 0.219565 0.678805 1.88927
3 4 0.961538 0.104011 -0.481165 0.850229
4 5 1.45342 1.05774 0.165562 0.515018
5 6 -1.33694 0.562861 1.39285 -0.063328
6 7 0.121668 1.2076 -0.00204021 1.6278
7 8 0.354493 1.03753 -0.385684 0.519818
8 9 1.68658 -1.32596 1.42898 -2.08935
9 10 -0.12982 0.631523 -0.586538 0.29072

当样式实际上不依赖于值时,请使用Styler.set_properties

在[23]:
df.style.set_properties(**{'background-color': 'black',
                           'color': 'lawngreen',
                           'border-color': 'white'})
出[23]:
一个BCDE
0 1 1.32921 -0.31628-0.99081
1 2 -1.07082-1.43871 0.564417 0.295722
2 3 -1.6264 0.219565 0.678805 1.88927
3 4 0.961538 0.104011 -0.481165 0.850229
4 5 1.45342 1.05774 0.165562 0.515018
5 6 -1.33694 0.562861 1.39285 -0.063328
6 7 0.121668 1.2076 -0.00204021 1.6278
7 8 0.354493 1.03753 -0.385684 0.519818
8 9 1.68658 -1.32596 1.42898 -2.08935
9 10 -0.12982 0.631523 -0.586538 0.29072

Sharing Styles

假设你有一个可爱的样式为DataFrame构建,现在你想要应用相同的样式到第二个DataFrame。使用df1.style.export导出样式,并使用df1.style.set在第二个DataFrame上导入样式

在[24]:
df2 = -df
style1 = df.style.applymap(color_negative_red)
style1
出[24]:
一个BCDE
0 1 1.32921 -0.31628-0.99081
1 2 -1.07082-1.43871 0.564417 0.295722
2 3 -1.6264 0.219565 0.678805 1.88927
3 4 0.961538 0.104011 -0.481165 0.850229
4 5 1.45342 1.05774 0.165562 0.515018
5 6 -1.33694 0.562861 1.39285 -0.063328
6 7 0.121668 1.2076 -0.00204021 1.6278
7 8 0.354493 1.03753 -0.385684 0.519818
8 9 1.68658 -1.32596 1.42898 -2.08935
9 10 -0.12982 0.631523 -0.586538 0.29072
在[25]:
style2 = df2.style
style2.use(style1.export())
style2
出[25]:
一个BCDE
0 -1-1.32921 0.31628 0.99081
1 -2 1.07082 1.43871 -0.564417-0.295722
2 -3 1.6264 -0.219565-0.678805-1.88927
3 -4-0.961538-0.104011 0.481165 -0.850229
4 -5-1.45342-1.05774-0.165562-0.515018
5 -6 1.33694 -0.562861-1.39285 0.063328
6 -7-0.121668-1.2076 0.00204021 -1.6278
7 -8-0.354493-1.03753 0.385684 -0.519818
8 -9-1.68658 1.32596 -1.42898 2.08935
9 -10 0.12982 -0.631523 0.586538 -0.29072

请注意,您可以共享样式,即使它们是数据感知。在他们使用的新DataFrame上重新评估样式。

Other options

你已经看到了几种数据驱动的样式方法。Styler还为不依赖于数据的样式提供了一些其他选项。

  • 精确
  • 字幕
  • 表格样式

这些都可以通过两种方式指定:

  • pandas.core.Styler的关键字参数
  • 调用.set _方法之一,例如.set_caption

使用的最佳方法取决于上下文。在构建许多应该都具有相同属性的样式化DataFrame时,使用Styler构造函数。对于交互式使用,.set _方法更方便。

Precision

您可以使用pandas的常规display.precision选项来控制浮点数的精度。

在[26]:
with pd.option_context('display.precision', 2):
    html = (df.style
              .applymap(color_negative_red)
              .apply(highlight_max))
html
出[26]:
一个BCDE
0 1 1.3 -0.32-0.99
1 2 -1.1-1.4 0.56 0.3
2 3 -1.6 0.22 0.68 1.9
3 4 0.96 0.1 -0.48 0.85
4 5 1.5 1.1 0.17 0.52
5 6 -1.3 0.56 1.4 -0.063
6 7 0.12 1.2 -0.002 1.6
7 8 0.35 1 -0.39 0.52
8 9 1.7 -1.3 1.4 -2.1
9 10 -0.13 0.63 -0.59 0.29

或者通过set_precision方法。

在[27]:
df.style\
  .applymap(color_negative_red)\
  .apply(highlight_max)\
  .set_precision(2)
出[27]:
一个BCDE
0 1 1.3 -0.32-0.99
1 2 -1.1-1.4 0.56 0.3
2 3 -1.6 0.22 0.68 1.9
3 4 0.96 0.1 -0.48 0.85
4 5 1.5 1.1 0.17 0.52
5 6 -1.3 0.56 1.4 -0.063
6 7 0.12 1.2 -0.002 1.6
7 8 0.35 1 -0.39 0.52
8 9 1.7 -1.3 1.4 -2.1
9 10 -0.13 0.63 -0.59 0.29

设置精度只影响打印数量;全精度值总是传递给您的样式函数。如果您想从头开始,可以使用df.round(2).style

Captions

可以通过几种方式添加常规表格标题。

在[28]:
df.style.set_caption('Colormaps, with a caption.')\
    .background_gradient(cmap=cm)
出[28]:
Colormaps, with a caption.
一个BCDE
0 1 1.32921 -0.31628-0.99081
1 2 -1.07082-1.43871 0.564417 0.295722
2 3 -1.6264 0.219565 0.678805 1.88927
3 4 0.961538 0.104011 -0.481165 0.850229
4 5 1.45342 1.05774 0.165562 0.515018
5 6 -1.33694 0.562861 1.39285 -0.063328
6 7 0.121668 1.2076 -0.00204021 1.6278
7 8 0.354493 1.03753 -0.385684 0.519818
8 9 1.68658 -1.32596 1.42898 -2.08935
9 10 -0.12982 0.631523 -0.586538 0.29072

Table Styles

下一个选项是“表样式”。这些是应用于整个表的样式,但不要查看数据。某些交换,包括像:hover这样的伪选择器只能以这种方式使用。

在[29]:
from IPython.display import HTML

def hover(hover_color="#ffff99"):
    return dict(selector="tr:hover",
                props=[("background-color", "%s" % hover_color)])

styles = [
    hover(),
    dict(selector="th", props=[("font-size", "150%"),
                               ("text-align", "center")]),
    dict(selector="caption", props=[("caption-side", "bottom")])
]
html = (df.style.set_table_styles(styles)
          .set_caption("Hover to highlight."))
html
Out [29]:
Hover to highlight.
一个BCDE
0 1 1.32921 -0.31628-0.99081
1 2 -1.07082-1.43871 0.564417 0.295722
2 3 -1.6264 0.219565 0.678805 1.88927
3 4 0.961538 0.104011 -0.481165 0.850229
4 5 1.45342 1.05774 0.165562 0.515018
5 6 -1.33694 0.562861 1.39285 -0.063328
6 7 0.121668 1.2076 -0.00204021 1.6278
7 8 0.354493 1.03753 -0.385684 0.519818
8 9 1.68658 -1.32596 1.42898 -2.08935
9 10 -0.12982 0.631523 -0.586538 0.29072

table_styles应该是字典列表。每个字典应该有选择符道具键。selector的值应为有效的CSS选择器。请记住,所有样式都已附加到id,每个样式器都是唯一的。此选择器除了idprops的值应该是('attribute','value')的元组列表。

table_styles非常灵活,但没有手动输入的乐趣。我们希望在大熊猫中收集一些有用的内容,或者在这里建立的工具的新包中优先选择。

CSS Classes

某些CSS类附加到单元格。

  • Index and Column names include index_name and level<k> where k is its level in a MultiIndex
  • 索引标签单元格包括
    • row_heading
    • row&lt; n&gt;其中n是行的数字位置
    • level&lt; k&gt;其中k是MultiIndex中的级别
  • 柱标记细胞包括
    • col_heading
    • col&lt; n&gt;其中n是列的数字位置
    • level&lt; k&gt;其中k是MultiIndex中的级别
  • 空白单元格包括blank
  • 数据单元包括数据

Limitations

  • DataFrame仅(使用Series.to_frame()。style)
  • 索引和列必须是唯一的
  • 没有大的repr,和性能不是很大;这是为了概要DataFrames
  • 您只能设置的样式,而不是索引或列
  • 您只能应用样式,不能插入新的HTML实体

其中一些将在未来得到解决。

Terms

  • 样式函数:传递到Styler.applyStyler.applymap并返回像'css attribute:value'
  • 内置样式函数:样式函数是Styler上的方法
  • 表格样式:具有两个键选择器道具的字典。selector t>是props将应用于的CSS选择器。props(属性,值)元组的列表。传递到Styler中的表格样式列表。

Fun stuff

这里有一些有趣的例子。

样式器与小部件相互交互。如果你正在查看这个在线,而不是自己运行笔记本,你错过了交互式调整调色板。

在[30]:
from IPython.html import widgets
@widgets.interact
def f(h_neg=(0, 359, 1), h_pos=(0, 359), s=(0., 99.9), l=(0., 99.9)):
    return df.style.background_gradient(
        cmap=sns.palettes.diverging_palette(h_neg=h_neg, h_pos=h_pos, s=s, l=l,
                                            as_cmap=True)
    )
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-30-62e68348ecde> in <module>()
      1 from IPython.html import widgets
----> 2 @widgets.interact
      3 def f(h_neg=(0, 359, 1), h_pos=(0, 359), s=(0., 99.9), l=(0., 99.9)):
      4     return df.style.background_gradient(
      5         cmap=sns.palettes.diverging_palette(h_neg=h_neg, h_pos=h_pos, s=s, l=l,

/home/joris/miniconda3/envs/docs/lib/python2.7/site-packages/IPython/utils/shimmodule.pyc in __getattr__(self, key)
     90             return import_item(name)
     91         except ImportError:
---> 92             raise AttributeError(key)

AttributeError: interact
在[31]:
def magnify():
    return [dict(selector="th",
                 props=[("font-size", "4pt")]),
            dict(selector="td",
                 props=[('padding', "0em 0em")]),
            dict(selector="th:hover",
                 props=[("font-size", "12pt")]),
            dict(selector="tr:hover td:hover",
                 props=[('max-width', '200px'),
                        ('font-size', '12pt')])
]
在[32]:
np.random.seed(25)
cmap = cmap=sns.diverging_palette(5, 250, as_cmap=True)
df = pd.DataFrame(np.random.randn(20, 25)).cumsum()

df.style.background_gradient(cmap, axis=1)\
    .set_properties(**{'max-width': '80px', 'font-size': '1pt'})\
    .set_caption("Hover to magify")\
    .set_precision(2)\
    .set_table_styles(magnify())
出[32]:
Hover to magify
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
0 0.23 1 -0.84-0.59-0.96-0.22-0.62 1.8 -2.1 0.87 -0.92-0.23 2.2 -1.3 0.076 -1.2 1.2 -1 1.1 -0.42 2.3 -2.6 2.8 0.68 -1.6
1 -1.7 1.6 -1.1-1.1 1 0.0037 -2.5 3.4 -1.7 1.3 -0.52-0.015 1.5 -1.1-1.9-1.1-0.68-0.81 0.35 -0.055 1.8 -2.8 2.3 0.78 0.44
2 -0.65 3.2 -1.8 0.52 2.2 -0.37-3 3.7 -1.9 2.5 0.21 -0.24-0.1-0.78-3-0.82-0.21-0.23 0.86 -0.68 1.4 -4.9 3 1.9 0.61
3 -1.6 3.7 -2.3 0.43 4.2 -0.43-3.9 4.2 -2.1 1.1 0.12 0.6 -0.89 0.27 -3.7-2.7-0.31-1.6 1.4 -1.8 0.91 -5.8 2.8 2.1 0.28
4 -3.3 4.5 -1.9-1.7 5.2 -1-3.8 4.7 -0.72 1.1 -0.18 0.83 -0.22-1.1-4.3-2.9-0.97-1.8 1.5 -1.8 2.2 -6.3 3.3 2.5 2.1
5 -0.84 4.2 -1.7-2 5.3 -0.99-4.1 3.9 -1.1-0.94 1.2 0.087 -1.8-0.11-4.5-0.85-2.1-1.4 0.8 -1.6 1.5 -6.5 2.8 2.1 3.8
6 -0.74 5.4 -2.1-1.1 4.2 -1.8-3.2 3.8 -3.2-1.2 0.34 0.57 -1.8 0.54 -4.4-1.8-4-2.6-0.2-4.7 1.9 -8.5 3.3 2.5 5.8
7 -0.44 4.7 -2.3-0.21 5.9 -2.6-1.8 5.5 -4.5-3.2-1.7 0.18 0.11 0.036 -6-0.45-6.2-3.9 0.71 -3.9 0.67 -7.3 3 3.4 6.7
8 0.92 5.8 -3.3-0.65 6 -3.2-1.8 5.6 -3.5-1.3-1.6 0.82 -2.4-0.4-6.1-0.52-6.6-3.5-0.043-4.6 0.51 -5.8 3.2 2.4 5.1
9 0.38 5.5 -4.5-0.8 7.1 -2.6-0.44 5.3 -2-0.33-0.8 0.26 -3.4-0.82-6.1-2.6-8.5-4.5 0.41 -4.7 1.9 -6.9 2.1 3 5.2
10 2.1 5.8 -3.9-0.98 7.8 -2.5-0.59 5.6 -2.2-0.71-0.46 1.8 -2.8 0.48 -6-3.4-7.8-5.5-0.7-4.6-0.52-7.7 1.5 5 5.8
11 1.9 4.5 -2.2-1.4 5.9 -0.49 0.017 5.8 -1-0.6 0.49 2 -1.5 1.9 -5.9-4.5-8.2-3.4-2.2-4.3-1.2-7.9 1.4 5.3 5.8
12 3.2 4.2 -3.1-2.3 5.9 -2.6 0.33 6.7 -2.8-0.2 1.9 2.6 -1.5 0.75 -5.3-4.5-7.6-2.9-2.2-4.8-1.1-9 2.1 6.4 5.6
13 2.3 4.5 -3.9-2 6.8 -3.3-2.2 8 -2.6-0.8 0.71 2.3 -0.16-0.46-5.1-3.8-7.6-4 0.33 -3.7-1-8.7 2.5 5.9 6.7
14 3.8 4.3 -3.9-1.6 6.2 -3.2-1.5 5.6 -2.9-0.33-0.97 1.7 3.6 0.29 -4.2-4.1-6.7-4.5-2.2-2.4-1.6-9.4 3.4 6.1 7.5
15 5.6 5.3 -4-2.3 5.9 -3.3-1 5.7 -3.1-0.33-1.2 2.2 4.2 1 -3.2-4.3-5.7-4.4-2.3-1.4-1.2-11 2.6 6.7 5.9
16 4.1 4.3 -2.4-3.3 6 -2.5-0.47 5.3 -4.8 1.6 0.23 0.099 5.8 1.8 -3.1-3.9-5.5-3-2.1-1.1-0.56-13 2.1 6.2 4.9
17 5.6 4.6 -3.5-3.8 6.6 -2.6-0.75 6.6 -4.8 3.6 -0.29 0.56 5.8 2 -2.3-2.3-5-3.2-3.1-2.4 0.84 -13 3.6 7.4 4.7
18 6 5.8 -2.8-4.2 7.1 -3.3-1.2 7.9 -4.9 1.4 -0.63 0.35 7.5 0.87 -1.5-2.1-4.2-2.5-2.5-2.9 1.9 -9.7 3.4 7.1 4.4
19 4 6.2 -4.1-4.1 7.2 -4.1-1.5 6.5 -5.2-0.24 0.0072 1.2 6.4 -2-2.6-1.7-5.2-3.3-2.9-1.7 1.6 -11 2.8 7.5 3.9

Extensibility

熊猫的核心是,并将继续是其“高性能,易于使用的数据结构”。考虑到这一点,我们希望DataFrame.style实现两个目标

  • 提供一个令人愉快的交互式API,并且对于许多任务都“足够好”
  • 为专用图书馆提供基础

如果您在此之上建立了一个优秀的图书馆,请告诉我们,我们将链接到它。

Subclassing

本节包含有关Styler实施的信息。由于功能是如此新,所有这一切都可能改变,甚至比最终使用的API。

当用户应用样式时(通过.apply.applymap或其中一个内置函数),我们实际上不计算任何内容。相反,我们将函数和参数附加到列表self._todo当询问(通常在.render中),我们将遍历列表并执行每个函数(这在self._compute()中。这些函数更新内部defaultdict(list)self.ctx,它将DataFrame行/列位置映射到CSS属性值对。

我们通过self._todo采取额外的步骤,以便我们可以导出样式并将其设置在其他Styler上。

呈现使用Jinja模板。.translate方法采用self.ctx并构建另一个字典,准备传递到Styler.template.render,Jinja模板。

Alternate templates

我们使用Jinja模板来构建HTML。模板存储为类变量Styler.template。。子类可以覆盖它。

class CustomStyle(Styler):
    template = Template("""...""")