【问题标题】:Pretty Printing a pandas dataframe漂亮地打印熊猫数据框
【发布时间】:2013-09-02 22:12:06
【问题描述】:

如何将 pandas 数据框打印为漂亮的基于文本的表格,如下所示?

+------------+---------+-------------+
| column_one | col_two |   column_3  |
+------------+---------+-------------+
|          0 |  0.0001 | ABCD        |
|          1 |  1e-005 | ABCD        |
|          2 |  1e-006 | long string |
|          3 |  1e-007 | ABCD        |
+------------+---------+-------------+

【问题讨论】:

    标签: python pandas dataframe printing


    【解决方案1】:

    我刚刚找到了一个很好的工具来满足这个需求,它叫做tabulate

    它打印表格数据并使用DataFrame

    from tabulate import tabulate
    import pandas as pd
    
    df = pd.DataFrame({'col_two' : [0.0001, 1e-005 , 1e-006, 1e-007],
                       'column_3' : ['ABCD', 'ABCD', 'long string', 'ABCD']})
    
    print(tabulate(df, headers='keys', tablefmt='psql'))
    
    +----+-----------+-------------+
    |    |   col_two | column_3    |
    |----+-----------+-------------|
    |  0 |    0.0001 | ABCD        |
    |  1 |    1e-05  | ABCD        |
    |  2 |    1e-06  | long string |
    |  3 |    1e-07  | ABCD        |
    +----+-----------+-------------+
    

    注意:

    要禁止所有类型数据的行索引,请传递 showindex="never"showindex=False

    【讨论】:

    • 如果您无法访问最前沿,您可以通过tabulate([list(row) for row in df.values], headers=list(df.columns)) 摆脱索引
    • 在行索引和列中有层次结构时效果不佳。
    • 确保您使用print(tabulate(df, **kwargs)) 而不仅仅是tabulate(df, **kwargs);后者将显示所有新行\n....
    • 要抑制左侧索引列,可能还需要添加showindex=False
    • 我真的很喜欢 pandastabulate 捆绑为可选依赖项并允许 df.to_tabular(*args, **kwargs)
    【解决方案2】:

    熊猫 >= 1.0

    如果您想要一个内置函数将您的数据转储到某个 github markdown 中,那么您现在就有了。看看to_markdown

    df = pd.DataFrame({"A": [1, 2, 3], "B": [1, 2, 3]}, index=['a', 'a', 'b'])  
    print(df.to_markdown()) 
    
    |    |   A |   B |
    |:---|----:|----:|
    | a  |   1 |   1 |
    | a  |   2 |   2 |
    | b  |   3 |   3 |
    

    这是 github 上的样子:

    请注意,您仍然需要安装 tabulate 软件包。

    【讨论】:

    • 我使用to_markdown 从我的脚本中发出降价,并将其传送到glow - (github) 以在终端中呈现降价并获得很好的结果。 (Script here)
    • @SeanBreckenridge 链接已损坏或无法从公众访问。
    • 啊,感谢您的 ping;已移至其他文件夹。这是permalink
    • 随着更多参数传递给tabulateto_markdown实际上支持20+种格式(github.com/astanin/python-tabulate#table-format)和许多其他关键字。
    【解决方案3】:

    一个简单的方法是输出为html,pandas does out of the box:

    df.to_html('temp.html')
    

    【讨论】:

      【解决方案4】:

      如果您在 Jupyter notebook 中,您可以运行以下代码以交互方式在格式良好的表格中显示数据框。

      此答案基于上面的 to_html('temp.html') 答案,但不是创建文件,而是直接在笔记本中显示格式正确的表格:

      from IPython.display import display, HTML
      
      display(HTML(df.to_html()))
      

      此代码归功于示例:Show DataFrame as table in iPython Notebook

      【讨论】:

        【解决方案5】:

        您可以使用prettytable 将表格呈现为文本。诀窍是将 data_frame 转换为内存中的 csv 文件并漂亮地读取它。代码如下:

        from StringIO import StringIO
        import prettytable    
        
        output = StringIO()
        data_frame.to_csv(output)
        output.seek(0)
        pt = prettytable.from_csv(output)
        print pt
        

        【讨论】:

        • 这是什么版本的熊猫?
        • AFAIK, prettytable 在很大程度上被认为是废弃软件。也很遗憾,因为它是一个不错的包裹。 :(
        • @dmn 所以不再维护了?
        • prettytable 自 2013 年 4 月 6 日以来没有发布过。tabulate 是其精神上的前身,并定期发布,最近一次发布于 2019 年 1 月 24 日。
        • prettytable 在爵士乐队的维护下复活了!欢呼! github.com/jazzband/prettytable
        【解决方案6】:

        我使用了 Ofer 的答案一段时间,发现它在大多数情况下都很棒。不幸的是,由于 pandas's to_csvprettytable 的 from_csv 之间的不一致,我不得不以不同的方式使用 prettytable。

        一个失败案例是一个包含逗号的数据框:

        pd.DataFrame({'A': [1, 2], 'B': ['a,', 'b']})
        

        Prettytable 引发表单错误:

        Error: Could not determine delimiter
        

        以下函数处理这种情况:

        def format_for_print(df):    
            table = PrettyTable([''] + list(df.columns))
            for row in df.itertuples():
                table.add_row(row)
            return str(table)
        

        如果您不关心索引,请使用:

        def format_for_print2(df):    
            table = PrettyTable(list(df.columns))
            for row in df.itertuples():
                table.add_row(row[1:])
            return str(table)
        

        【讨论】:

        • 嗨,format_for_print() 函数似乎没有打印 Pandas DataFrame 的索引。我使用df.index.name = 'index' 设置索引,但这不会打印带有名称的索引列。
        【解决方案7】:

        跟进马克的回答,如果您出于某种原因使用 Jupyter,例如如果您想在控制台上进行一些快速测试,可以使用 DataFrame.to_string 方法,该方法至少从 Pandas 0.12 (2014) 开始有效。

        import pandas as pd
        
        matrix = [(1, 23, 45), (789, 1, 23), (45, 678, 90)]
        df = pd.DataFrame(matrix, columns=list('abc'))
        print(df.to_string())
        
        #  outputs:
        #       a    b   c
        #  0    1   23  45
        #  1  789    1  23
        #  2   45  678  90
        

        【讨论】:

        【解决方案8】:

        也许您正在寻找这样的东西:

        def tableize(df):
            if not isinstance(df, pd.DataFrame):
                return
            df_columns = df.columns.tolist() 
            max_len_in_lst = lambda lst: len(sorted(lst, reverse=True, key=len)[0])
            align_center = lambda st, sz: "{0}{1}{0}".format(" "*(1+(sz-len(st))//2), st)[:sz] if len(st) < sz else st
            align_right = lambda st, sz: "{0}{1} ".format(" "*(sz-len(st)-1), st) if len(st) < sz else st
            max_col_len = max_len_in_lst(df_columns)
            max_val_len_for_col = dict([(col, max_len_in_lst(df.iloc[:,idx].astype('str'))) for idx, col in enumerate(df_columns)])
            col_sizes = dict([(col, 2 + max(max_val_len_for_col.get(col, 0), max_col_len)) for col in df_columns])
            build_hline = lambda row: '+'.join(['-' * col_sizes[col] for col in row]).join(['+', '+'])
            build_data = lambda row, align: "|".join([align(str(val), col_sizes[df_columns[idx]]) for idx, val in enumerate(row)]).join(['|', '|'])
            hline = build_hline(df_columns)
            out = [hline, build_data(df_columns, align_center), hline]
            for _, row in df.iterrows():
                out.append(build_data(row.tolist(), align_right))
            out.append(hline)
            return "\n".join(out)
        
        
        df = pd.DataFrame([[1, 2, 3], [11111, 22, 333]], columns=['a', 'b', 'c'])
        print tableize(df)
        
        输出: +-------+----+-----+ |一个 |乙 | c | +-------+----+-----+ | 1 | 2 | 3 | | 11111 | 22 | 333 | +-------+----+-----+

        【讨论】:

          猜你喜欢
          • 2019-02-12
          • 2021-06-22
          • 2017-12-10
          • 1970-01-01
          • 2018-05-10
          • 1970-01-01
          • 2019-08-25
          • 1970-01-01
          • 2015-01-22
          相关资源
          最近更新 更多