簡體   English   中英

在Pandas DataFrame中的字符串中打印相當漂亮的線條

[英]Pretty printing newlines inside a string in a Pandas DataFrame

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

如果您嘗試在ipython筆記本中執行此操作,則可以執行以下操作:

from IPython.display import display, HTML

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

來自pandas.DataFrame 文檔

具有標記軸(行和列)的二維大小可變,可能異構的表格數據結構。 算術運算在行標簽和列標簽上對齊。 可以被認為是Series對象的類似dict的容器。 主要的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作為列,並為數據中的每個鍵/人創建一個新行。 在下面的代碼示例中,它打印DataFrame,其中NaN值替換為空字符串。

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])

這取決於你想要對數據做什么。 祝好運 :)

有點與未分類的答案一致:

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_html在內部調用。 如果您想要原始函數,請調用base_to_html (或您命名的任何內容)。

我正在使用jupyter 1.0.0notebook 5.7.6

使用pandas .set_properties()和CSS 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',
})

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM