簡體   English   中英

將pandas數據幀的“Out []”表保存為數字

[英]Save the “Out[]” table of a pandas dataframe as a figure

這似乎是一個無用的功能,但它對我非常有幫助。 我想保存Canopy IDE中的輸出。 我不認為這是Canopy特有的,但為了清楚起見,這就是我使用的。 例如,我的控制台Out [2]是我想要的:

在此輸入圖像描述

我認為格式化非常好並且每次重現這一點而不僅僅是保存輸出將是浪費時間。 所以我的問題是,我怎樣才能掌握這個數字呢? 理想情況下,實施方式與標准方法類似,因此可以這樣做:

from matplotlib.backends.backend_pdf import PdfPages

pp = PdfPages('Output.pdf')
fig = plt.figure() 
ax = fig.add_subplot(1, 1, 1)
df.plot(how='table')
pp.savefig()
pp.close()

注意:我意識到之前已經問過一個非常類似的問題( 如何將Pandas數據幀/系列數據保存為數字? )但它從未收到答案,我想我已經更清楚地說明了這個問題。

這是一個有點hackish的解決方案,但它完成了工作。 你想要一個.pdf,但你得到獎金.png。 :)

import numpy as np
import pandas as pd
from matplotlib.backends.backend_pdf import PdfPages
import matplotlib.pyplot as plt

from PySide.QtGui import QImage
from PySide.QtGui import QPainter
from PySide.QtCore import QSize
from PySide.QtWebKit import QWebPage

arrays = [np.hstack([ ['one']*3, ['two']*3]), ['Dog', 'Bird', 'Cat']*2]
columns = pd.MultiIndex.from_arrays(arrays, names=['foo', 'bar'])
df =pd.DataFrame(np.zeros((3,6)),columns=columns,index=pd.date_range('20000103',periods=3))

h = "<!DOCTYPE html> <html> <body> <p> " + df.to_html() + " </p> </body> </html>";
page = QWebPage()
page.setViewportSize(QSize(5000,5000))

frame = page.mainFrame()
frame.setHtml(h, "text/html")

img = QImage(1000,700, QImage.Format(5))
painter = QPainter(img)
frame.render(painter)
painter.end()
a = img.save("html.png")

pp = PdfPages('html.pdf')
fig = plt.figure(figsize=(8,6),dpi=1080) 
ax = fig.add_subplot(1, 1, 1)
img2 = plt.imread("html.png")
plt.axis('off')
ax.imshow(img2)
pp.savefig()
pp.close()

編輯歡迎。

我相信,它是IDE正在呈現的HTML表。 這就是ipython筆記本所做的。

你可以這樣得到一個句柄:

from IPython.display import HTML
import pandas as pd
data = pd.DataFrame({'spam':['ham','green','five',0,'kitties'],
                     'eggs':[0,1,2,3,4]})
h = HTML(data.to_html())
h

並保存到HTML文件:

my_file = open('some_file.html', 'w')
my_file.write(h.data)
my_file.close()

我認為這里需要的是在輸出到pdf的圖形中將表格輸出到pdf文件的一致方法。

我的第一個想法是不使用matplotlib后端即

from matplotlib.backends.backend_pdf import PdfPages

因為它似乎在格式化選項方面有限,並傾向於將表格式化為圖像(從而以不可選擇的格式呈現表格的文本)

如果你想在不使用matplotlib pdf后端的情況下在PDF格式中混合數據框輸出和matplotlib圖,我可以想到兩種方法。

  1. 像以前一樣生成matplotlib數據的pdf,然后插入包含dataframe表的頁面。 我認為這是一個困難的選擇。
  2. 使用其他庫生成pdf。 我在下面說明了一個選項。

首先,安裝xhtml2pdf庫。 這看起來有點不太受支持,但在Github上活躍的,並且在這里有一些基本的用法文檔 你可以通過pippip install xhtml2pdf安裝它

一旦你完成了這個,這里是一個簡單的例子,嵌入一個matplotlib圖,然后是表(所有文本可選),然后是另一個圖。 您可以使用CSS等將格式更改為您的確切規格,但我認為這符合以下簡要說明:

from xhtml2pdf import pisa             # this is the module that will do the work
import numpy as np
import pandas as pd
from matplotlib.backends.backend_pdf import PdfPages
import matplotlib.pyplot as plt

# Utility function
def convertHtmlToPdf(sourceHtml, outputFilename):
    # open output file for writing (truncated binary)
    resultFile = open(outputFilename, "w+b")

    # convert HTML to PDF
    pisaStatus = pisa.CreatePDF(
            sourceHtml,                # the HTML to convert
            dest=resultFile,           # file handle to recieve result
            path='.')                  # this path is needed so relative paths for 
                                       # temporary image sources work

    # close output file
    resultFile.close()                 # close output file

    # return True on success and False on errors
    return pisaStatus.err

# Main program
if __name__=='__main__':   

    arrays = [np.hstack([ ['one']*3, ['two']*3]), ['Dog', 'Bird', 'Cat']*2]
    columns = pd.MultiIndex.from_arrays(arrays, names=['foo', 'bar'])
    df = pd.DataFrame(np.zeros((3,6)),columns=columns,index=pd.date_range('20000103',periods=3))

    # Define your data
    sourceHtml = '<html><head>'         
    # add some table CSS in head
    sourceHtml += '''<style>
                     table, td, th {
                           border-style: double;
                           border-width: 3px;
                     }

                     td,th {
                           padding: 5px;
                     }
                     </style>'''
    sourceHtml += '</head><body>'
    #Add a matplotlib figure(s)
    plt.plot(range(20))
    plt.savefig('tmp1.jpg')
    sourceHtml += '\n<p><img src="tmp1.jpg"></p>'

    # Add the dataframe
    sourceHtml += '\n<p>' + df.to_html() + '</p>'

    #Add another matplotlib figure(s)
    plt.plot(range(70,100))
    plt.savefig('tmp2.jpg')
    sourceHtml += '\n<p><img src="tmp2.jpg"></p>'

    sourceHtml += '</body></html>'
    outputFilename = 'test.pdf'

    convertHtmlToPdf(sourceHtml, outputFilename)

注意在編寫本文時,xhtml2pdf中似乎存在一個錯誤,這意味着某些CSS不受尊重。 與這個問題特別相關的是,似乎不可能在桌子周圍獲得雙重邊界


編輯

在回復評論中,顯而易見的是,一些用戶(至少@Keith都回答並授予了賞金!)希望表可選,但絕對是在matplotlib軸上。 這與原始方法保持一致。 因此 - 這是一個使用pdf后端的方法,僅用於matplotlib和matplotlib對象。 我不認為該表看起來不錯 - 特別是分層列標題的顯示,但我猜這是一個選擇問題。 我非常感謝這個答案和評論格式化表格顯示軸的方法。

import numpy as np
import pandas as pd
from matplotlib.backends.backend_pdf import PdfPages
import matplotlib.pyplot as plt

# Main program
if __name__=='__main__':   
    pp = PdfPages('Output.pdf')
    arrays = [np.hstack([ ['one']*3, ['two']*3]), ['Dog', 'Bird', 'Cat']*2]
    columns = pd.MultiIndex.from_arrays(arrays, names=['foo', 'bar'])
    df =pd.DataFrame(np.zeros((3,6)),columns=columns,index=pd.date_range('20000103',periods=3))

    plt.plot(range(20))
    pp.savefig()
    plt.close()

    # Calculate some sizes for formatting - constants are arbitrary - play around
    nrows, ncols = len(df)+1, len(df.columns) + 10
    hcell, wcell = 0.3, 1.
    hpad, wpad = 0, 0   

    #put the table on a correctly sized figure    
    fig=plt.figure(figsize=(ncols*wcell+wpad, nrows*hcell+hpad))
    plt.gca().axis('off')
    matplotlib_tab = pd.tools.plotting.table(plt.gca(),df, loc='center')    
    pp.savefig()
    plt.close()

    #Add another matplotlib figure(s)
    plt.plot(range(70,100))
    pp.savefig()
    plt.close()

    pp.close()

暫無
暫無

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

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