在Pandas DataFrame中的字符串中打印相当漂亮的线条

时间:2015-12-16 21:28:00

标签: python string python-3.x pandas printing

我有一个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)

4 个答案:

答案 0 :(得分:10)

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

from IPython.display import display, HTML

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

答案 1 :(得分:2)

来自pandas.DataFrame documention

  

二维大小可变,可能异构的表格数据   带有标记轴(行和列)的结构。算术运算   在行标签和列标签上对齐。可以被认为是一个像字典一样   Series对象的容器。主要的pandas数据结构

所以你不能没有索引的行。换行符&#34; \ n&#34;不能在DataFrame中工作。

你可以覆盖&#39; pos&#39;使用空值,并输出下一个“出价人”&#39;在下一行。但随后索引和&#39; pos&#39;每次你这样做都会被抵消。喜欢:

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

因此,如果出价人员打电话给“坦率”的话。有4个值,它会覆盖&#39; bob&#39;。当您添加更多内容时,这会导致问题。可能使用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])

这取决于你想要对数据做什么。祝你好运:)

答案 2 :(得分:1)

有点符合未排序的答案

static Blank[] copy(Blank[] ts){
    Blank[] ts_copy = new Blank[ts.length];
    for (int i=0; i<ts.length; i++) {
        ts_copy[i] = ts[i].clone();
    }
    return ts_copy;
}

这样,您无需在Jupyter笔记本中调用任何显式函数,因为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/>")) ) 是在内部调用的。如果您想要原始功能,请调用to_html(或任何您命名的功能)。

我正在使用base_to_htmljupyter 1.0.0

答案 3 :(得分:1)

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

[用于IPython笔记本]

另一种方法是使用熊猫的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',
})