将Pandas DataFrame的列名旋转

18

我正在尝试使用pandas制作格式良好的表格。我的某些列名太长了。这些列的单元格很大,导致整个表格一团糟。

在我的例子中,是否有可能旋转显示列名?

data = [{'Way too long of a column to be reasonable':4,'Four?':4},
        {'Way too long of a column to be reasonable':5,'Four?':5}]
pd.DataFrame(data)

I would like to rotate the names of the columns as displayed here.


1
请您添加标签 jupyter notebook - BENY
显然这取决于您的情况,但也许缩短/改进列名是有意义的?但作为一种解决方法,您可以考虑转换为“伪”多索引。例如,如果列名为“david s pumpkins”,则可以将“david s”作为顶级,将“pumpkins”作为第二级。显然,这不是多索引的用途,但我认为它基本上可以实现您想要的功能。 - JohnE
@JohnE,感谢您的建议。文本换行是@Wen建议的,但已被删除,原来是:df.style.set_table_styles([dict(selector="th",props=[('max-width', '50px')])])。这是一个很好的解决方法,适用于像我例子中的短语。但我也有很长的单词。我仍然很想知道是否可能旋转!我不是CSS选择器专家,但我认为这应该可以工作,但实际上并没有:dfoo.style.set_table_styles([dict(selector="th",props=[('text-orientation', 'upright')])]) - Dan Fiorino
我刚刚重新阅读了文档页面(http://pandas.pydata.org/pandas-docs/version/0.19.2/style.html),其中指出“您只能为值设置样式,而不能为索引或列设置样式”,但是文档显示列和索引被格式化。也许这只是开始得到解决。 - Dan Fiorino
5个回答

16

类似这样的内容:

data = [{'Way too long of a column to be reasonable':4,'Four?':4},
        {'Way too long of a column to be reasonable':5,'Four?':5}]
dfoo = pd.DataFrame(data)
dfoo.style.set_table_styles(
    [dict(selector="th",props=[('max-width', '80px')]),
        dict(selector="th.col_heading",
                 props=[("writing-mode", "vertical-rl"), 
                        ('transform', 'rotateZ(-90deg)'),
                        ])]
)

可能接近您所需的内容:

在此输入图像描述

在此处查看结果


更改我的已接受答案。这个任务只使用Pandas库完成,并将在JupyterLab中显示。干得好! - Dan Fiorino
2
我发现(在Firefox中),rotateZ(-90deg)参数会导致标题旋转回来,使它们再次变为水平。使用('vertical-align', 'text-top'), ('transform', 'rotateZ(180deg)'),可以得到更好的布局,这样可以将文本沿着表格的第一行对齐。 - Nate
根据@Nate的评论,正确旋转列名的设置是props=[('vertical-align', 'text-top'), ('transform', 'rotateZ(-90deg)')] - Paul Rougieux

3

查看已接受答案的解决方案的pybloqs源代码,我能够找到如何旋转列而无需安装pybloqs。请注意,这也会旋转索引,但我已添加了代码以删除它们。

from IPython.display import HTML, display

data = [{'Way too long of a column to be reasonable':4,'Four?':4},
        {'Way too long of a column to be reasonable':5,'Four?':5}]
df = pd.DataFrame(data)

styles = [
    dict(selector="th", props=[("font-size", "125%"),
                               ("text-align", "center"),
                              ("transform", "translate(0%,-30%) rotate(-5deg)")
                              ]),
    dict(selector=".row_heading, .blank", props= [('display', 'none;')])
]

html = df.style.set_table_styles(styles).render()
display(HTML(html))

enter image description here


3
我将@Bobain的好回答放入一个函数中,这样我可以在整个笔记本中重复使用它。
def format_vertical_headers(df):
    """Display a dataframe with vertical column headers"""
    styles = [dict(selector="th", props=[('width', '40px')]),
              dict(selector="th.col_heading",
                   props=[("writing-mode", "vertical-rl"),
                          ('transform', 'rotateZ(180deg)'), 
                          ('height', '290px'),
                          ('vertical-align', 'top')])]
    return (df.fillna('').style.set_table_styles(styles))

format_vertical_headers(pandas.DataFrame(data))

enter image description here


我没有得到相同的布局 - 文本是倒置的水平和换行的。没有足够的空间来解释我尝试不同参数所取得的有限进展。也许可以添加另一个评论来解释它们?print(pd.version) 表示我的 pandas 版本为 1.2,1,jupyter 版本为 jupyter core: 4.7.1 jupyter-notebook: 6.4.3 qtconsole: 未安装 ipython: 7.26.0 ipykernel: 6.1.0 jupyter client: 6.1.12 jupyter lab: 3.1.6 nbconvert: 6.1.0 ipywidgets: 未安装 nbformat: 5.1.3 traitlets: 5.0.5 - Bill
我找到的最好的模块如下,但仍然不是垂直的:def format_vertical_headers(df): """显示具有垂直列标题的数据框""" styles = [dict(selector="th", props=[('width', '40px')]), dict(selector="th.col_heading", props=[("writing-mode", "vertical-rl"), ('transform', 'rotateZ(180deg)'), ('height', '290px'), ('vertical-align', 'top')])] return (df.fillna('').style.set_table_styles(styles))format_vertical_headers(pd.DataFrame(data)) - Bill
@Bill,请提出一个新问题并提供一个可重现的示例。可重现的示例 - Paul Rougieux

2
使用Python库“pybloqs”(http://pybloqs.readthedocs.io/en/latest/),可以旋转列名并在顶部添加填充。唯一的缺点(正如文档所述)是顶部填充不与Jupyter内联工作。表必须导出。
import pandas as pd
from pybloqs import Block
import pybloqs.block.table_formatters as tf
from IPython.core.display import display, HTML

data = [{'Way too long of a column to be reasonable':4,'Four?':4},
        {'Way too long of a column to be reasonable':5,'Four?':5}]
dfoo =pd.DataFrame(data)

fmt_header = tf.FmtHeader(fixed_width='5cm',index_width='10%', 
                          top_padding='10cm', rotate_deg=60)
table_block = Block(dfoo, formatters=[fmt_header])

display(HTML(table_block.render_html()))
table_block.save('Table.html')

Table in HTML with rotated column names


1
我可以使文本完全旋转90度,但是无法弄清如何使用text-orientation: upright,因为它只会使文本不可见:(你缺少必须设置的writing-mode属性,才能使text-orientation生效。此外,我通过稍微修改选择器,使其仅适用于列标题。

dfoo.style.set_table_styles([dict(selector="th.col_heading",props=[("writing-mode", "vertical-lr"),('text-orientation', 'upright')])])

希望这让你离目标更近了一步!


这绝对是越来越热了!所有的单个字母都至少旋转了 - Dan Fiorino

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接