在 Pandas DataFrame 的字符串内漂亮地打印换行符

Pretty printing newlines inside a string in a Pandas DataFrame

提问人:shadowtalker 提问时间:12/17/2015 更新时间:8/11/2023 访问量:48276

问:

我有一个 Pandas DataFrame,其中一列包含字符串元素,这些字符串元素包含我想按字面打印的新行。但它们只是在输出中显示。\n

也就是说,我想打印这个:

  pos     bidder
0   1
1   2
2   3  <- alice
       <- bob
3   4

但这就是我得到的:

  pos            bidder
0   1
1   2
2   3  <- alice\n<- bob
3   4

我怎样才能实现我想要的?是否可以使用 DataFrame,或者是否必须恢复到一次手动打印一行填充列?

这是我目前所拥有的:

n = 4
output = pd.DataFrame({
    'pos': range(1, n+1),
    'bidder': [''] * n
})
bids = {'alice': 3, 'bob': 3}
used_pos = []
for bidder, pos in bids.items():
    if pos in used_pos:
        arrow = output.ix[pos, 'bidder']
        output.ix[pos, 'bidder'] = arrow + "\n<- %s" % bidder
    else:
        output.ix[pos, 'bidder'] = "<- %s" % bidder
print(output)
字符串 python-3.x pandas 打印

评论


答:

5赞 oystein-hr 12/17/2015 #1

来自熊猫。DataFrame 文档

二维大小可变、潜在的异构表格数据 具有标记轴(行和列)的结构。算术运算 在行标签和列标签上对齐。可以认为是字典式 Series 对象的容器。主要的 pandas 数据结构

因此,没有索引就不能有行。换行符“\n”在 DataFrame 中不起作用。

您可以用空值覆盖“pos”,并在下一行输出下一个“bidder”。但是每次你这样做时,索引和“pos”都会被抵消。喜欢:

  pos    bidder
0   1          
1   2          
2   3  <- alice
3        <- bob
4   5   

因此,如果一个名为“frank”的投标人将 4 作为价值,它将覆盖“bob”。当您添加更多内容时,这会导致问题。也许可以使用 DataFrame 并编写代码来解决此问题,但可能值得研究其他解决方案。

下面是生成上述输出结构的代码。

import pandas as pd

n = 5
output = pd.DataFrame({'pos': range(1, n + 1),
                      'bidder': [''] * n},
                      columns=['pos', 'bidder'])
bids = {'alice': 3, 'bob': 3}
used_pos = []
for bidder, pos in bids.items():
    if pos in used_pos:
        output.ix[pos, 'bidder'] = "<- %s" % bidder
        output.ix[pos, 'pos'] = ''
    else:
        output.ix[pos - 1, 'bidder'] = "<- %s" % bidder
        used_pos.append(pos)
print(output)

编辑:

另一种选择是重构数据和输出。你可以 将 POS 作为列,并为每个键/人员创建一个新行 在数据中。在下面的代码示例中,它使用 NaN 打印 DataFrame 值替换为空字符串。

import pandas as pd

data = {'johnny\nnewline': 2, 'alice': 3, 'bob': 3,
        'frank': 4, 'lisa': 1, 'tom': 8}
n = range(1, max(data.values()) + 1)

# Create DataFrame with columns = pos
output = pd.DataFrame(columns=n, index=[])

# Populate DataFrame with rows
for index, (bidder, pos) in enumerate(data.items()):
    output.loc[index, pos] = bidder

# Print the DataFrame and remove NaN to make it easier to read.
print(output.fillna(''))

# Fetch and print every element in column 2
for index in range(1, 5):
    print(output.loc[index, 2])

不过,这取决于您想如何处理数据。祝你好运:)

评论

1赞 shadowtalker 12/17/2015
有趣的是,尽管我在定义中没有看到任何阻止 DataFrame 在元素中包含换行符的内容。例如,该原理在 R 中工作得很好。无论哪种方式,我最终都可能只是使用字符串格式逐行完成。
0赞 oystein-hr 12/17/2015
如果从包含例如“johnny\nnewline”的 DataFrame 中获取一个元素并打印该元素,它将在一行上打印“johnny”,在新行上打印“newline”。添加另一个选项,并打印示例来回答。
44赞 unsorted 9/20/2017 #2

如果您尝试在 ipython 笔记本中执行此操作,您可以执行以下操作:

from IPython.display import display, HTML

def pretty_print(df):
    return display( HTML( df.to_html().replace("\\n","<br>") ) )

评论

0赞 Julio Cezar Silva 1/20/2021
快速干净,无需更改设置,只需笔记本专用的单行本。这是给我的。
6赞 Roger d'Amiens 3/15/2019 #3

有点符合 unsorted 的回答:

import pandas as pd

# Save the original `to_html` function to call it later
pd.DataFrame.base_to_html = pd.DataFrame.to_html
# Call it here in a controlled way
pd.DataFrame.to_html = (
    lambda df, *args, **kwargs: 
        (df.base_to_html(*args, **kwargs)
           .replace(r"\n", "<br/>"))
)

这样,您就不需要在 Jupyter 笔记本中调用任何显式函数,因为在内部调用。如果您想要原始函数,请调用(或您命名的任何函数)。to_htmlbase_to_html

我正在使用 , .jupyter 1.0.0notebook 5.7.6

评论

0赞 Craig Nathan 6/7/2021
这是否可在 python 脚本中使用 - 没有 jupyter 笔记本?
27赞 yongjieyongjie 7/4/2019 #4

使用 pandas 和 CSS 属性.set_properties()white-space

[用于 IPython 笔记本]

另一种方法是使用 pandas 的 pandas.io.formats.style.Styler.set_properties() 方法和 CSS “white-space”: “pre-wrap” 属性:

from IPython.display import display

# Assuming the variable df contains the relevant DataFrame
display(df.style.set_properties(**{
    'white-space': 'pre-wrap',
}))

要使文本保持左对齐,您可能需要添加如下内容:'text-align': 'left'

from IPython.display import display

# Assuming the variable df contains the relevant DataFrame
display(df.style.set_properties(**{
    'text-align': 'left',
    'white-space': 'pre-wrap',
}))

评论

0赞 max 10/4/2022
不幸的是,它不适用于大型数据帧:“对象<类'pandas.io.formats.style.Styler'>太大而无法序列化;估计 104360172 字节;限制 20000000”。(即使数据帧在其他方面都表现良好),