2016-06-29 2 views
2

Ich versuche, einen Datenrahmen mit Multi-Index in einem Bericht in PDF aufzunehmen. Ich hätte gerne eine schöne Tabellenausgabe. > HTML - -> pdfSpeichern Sie ein Pandas Dataframe als Tabelle in Bild oder PDF-Dokument mit schönen Multi-Index-Anzeige

import pandas as pd 
    from IPython.display import HTML 
    import pdfkit 

    # df generation 
    df = pd.read_csv(path_to_csv, sep =',') 
    groupeddf = df.groupby('Cluster') 
    res = groupeddf.describe([0.05, 0.5, 0.95]) 
    res.index.rename(['Cluster', 'stats'], inplace=True) 

    res['Cluster'] = res.index.get_level_values('Cluster') 
    res['stats'] = res.index.get_level_values('stats') 
    populations = (res.iloc[(res.index.get_level_values('stats') == 'count'), \ 
                  0].values).tolist() 
    res['population'] = [populations[i] for i in res.index.labels[0].values()] 
    total_pop = sum(populations) 
    res['frequency'] =(res['population']/total_pop).round(3) 
    res.set_index(['Cluster', 'population','frequency', 'stats'], inplace=True) 



    res1 = res.iloc[(res.index.get_level_values('stats') == '5%') | 
    (res.index.get_level_values('stats') == 'mean') | 
    (res.index.get_level_values('stats') == '50%') | 
    (res.index.get_level_values('stats') == '95%')] 
    res1 = res1.round(2) 
    # saving the df  
    h = HTML(res1.to_html()) 
    my_file = open('test.html', 'w') 
    my_file.write(h.data) 
    my_file.close() 


    options = { 
     'orientation': 'Landscape' 
     } 
    with open('test.html') as f: 
     pdfkit.from_file(f, 'out.pdf', options=options) 

Das hat aber eine Abhängigkeit von pdfkit, die es uns schwer machen

pandas.df:

Ich habe diese zwei Lösungen gefunden. Deshalb versuche ich, pandas.df zu verwenden -> tex -> pdf (wie in Export a Pandas dataframe as a table image erwähnt)

import pandas as pd 
    import os 
    # df generation    
    df = pd.read_csv(path_to_csv, sep =',') 
    groupeddf = df.groupby('Cluster') 
    res = groupeddf.describe([0.05, 0.5, 0.95]) 
    res.index.rename(['Cluster', 'stats'], inplace=True) 

    res['Cluster'] = res.index.get_level_values('Cluster') 
    res['stats'] = res.index.get_level_values('stats') 
    populations = (res.iloc[(res.index.get_level_values('stats') == 'count'), \ 
                  0].values).tolist() 
    res['population'] = [populations[i] for i in res.index.labels[0].values()] 
    total_pop = sum(populations) 
    res['frequency'] =(res['population']/total_pop).round(3) 
    res.set_index(['Cluster', 'population','frequency', 'stats'], inplace=True) 



    res1 = res.iloc[(res.index.get_level_values('stats') == '5%') | 
    (res.index.get_level_values('stats') == 'mean') | 
    (res.index.get_level_values('stats') == '50%') | 
    (res.index.get_level_values('stats') == '95%')] 
    res1 = res1.round(2) 
    res1.rename(columns=lambda x: x.replace('_', ' '), inplace=True)  

    #latex 
    template = r'''\documentclass[preview]{{standalone}} 
    \usepackage{{booktabs}} 
    \begin{{document}} 
    {} 
    \end{{document}} 
    ''' 

    with open("outputfile.tex", "wb") as afile: 
     afile.write(template.format(res1.to_latex())) 
    os.system("pdflatex outputfile.tex") 

Allerdings bin ich nicht vertraut mit Latex, und ich bekomme diese Fehlermeldung:

! LaTeX Error: File `standalone.cls' not found. 

Type X to quit or <RETURN> to proceed, 
or enter a new name. (Default extension: cls) 

Irgendeine Idee über den Fehler oder die Standardmethode, pandas.df zu machen -> pdf?

Antwort

2

Die Lösung, die für mich funktioniert: Mit pandas> = 0.17 Ich habe pdflatex installiert. Ich kopierte Latex-Paket wie booktabs.sty, geography.sty und pdflscape.sty

import pandas as pd 
import os 
import math 

def save_summary_table_as_pdf(path_to_csv, path_to_output_folder): 
    pwd = os.getcwd() 
    df = pd.read_csv(path_to_csv, sep =',') 

    #data preparation 
    groupeddf = df.groupby('Cluster') 
    res = groupeddf.describe([0.05, 0.5, 0.95]) 
    res.index.rename(['Cluster', 'Stats'], inplace=True) 

    res['cluster'] = res.index.get_level_values('Cluster') 
    res['stats'] = res.index.get_level_values('Stats') 
    populations = (res.iloc[(res.index.get_level_values('Stats') == 'count'), \ 
                  0].values).tolist() 
    res['population'] = [populations[i] for i in res.index.labels[0].values()] 
    total_pop = sum(populations) 
    res['frequency'] =(res['population']/total_pop).round(3) 
    res.set_index(['cluster', 'population','frequency', 'stats'], inplace=True) 
    res1 = res.iloc[(res.index.get_level_values('stats') == '5%') | 
    (res.index.get_level_values('stats') == 'mean') | 
    (res.index.get_level_values('stats') == '50%') | 
    (res.index.get_level_values('stats') == '95%')] 
    res1 = res1.round(2) 
    res1.rename(columns=lambda x: x.replace('_', ' '), inplace=True) 

    #latex 
    nbpages = int(math.ceil(res1.shape[0]*1.0/40)) 

    templatetop = r'''\documentclass[a3paper, 5pt]{article} 
    \usepackage{booktabs} 
    \usepackage{pdflscape} 
    \usepackage[a4paper,bindingoffset=0.2in,% 
      left=0.25in,right=0.25in,top=1in,bottom=1in,% 
      footskip=.25in]{geometry} 
    \begin{document} 
    \begin{landscape} 
    \pagenumbering{gobble} 
    \oddsidemargin = 0pt 
    \hoffset = -0.25in 
    \topmargin = 1pt 
    \headheight = 0pt 
    \headsep = 0pt 
    ''' 
    templatebottom = ''' 
    \end{landscape} 
    \end{document} 
    ''' 
    output_folder_path_abs = path_to_output_folder 
    output_tex = os.path.join(output_folder_path_abs, 
    "clustering_summary_table.tex") 

    with open(output_tex, "wb") as afile: 
     afile.write(templatetop +'\n') 
     for i in range(0, nbpages): 
      afile.write(res1.iloc[(i*40):((i+1)*40), :].to_latex() +'\n' + 
               """\pagenumbering{gobble}""") 
     afile.write(templatebottom +'\n') 
    os.chdir(output_folder_path_abs) 
    os.system('pdflatex clustering_summary_table.tex') 
    os.chdir(pwd) 
    os.remove(output_tex) 
    os.remove(os.path.join(path_to_output_folder, 
              'clustering_summary_table.aux')) 
    os.remove(os.path.join(path_to_output_folder, 
              'clustering_summary_table.log')) 

if __name__ == "__main__": 
    print 'begin generate pdf table about clustering' 
    import argparse 
    parser = argparse.ArgumentParser() 
    parser.add_argument("path_to_csv") 
    parser.add_argument("outputfolder") 
    args = vars(parser.parse_args()) 
    filedir = os.path.abspath(os.path.dirname(__file__)) 
    output_folder_path_abs = os.path.abspath(args['outputfolder']) 
    input_folder_path_abs = os.path.abspath(args['path_to_csv']) 
    # copy the user package latex to the folder 
    os.system('scp ' 
    +os.path.abspath(os.path.join(filedir, 'userpackagelatex/booktabs.sty'))+ 
    ' ' +output_folder_path_abs) 
    os.system('scp ' 
    +os.path.abspath(os.path.join(filedir, 'userpackagelatex/geography.sty'))+ 
    ' ' +output_folder_path_abs) 
    os.system('scp ' 
    +os.path.abspath(os.path.join(filedir, 'userpackagelatex/pdflscape.sty'))+ 
    ' ' +output_folder_path_abs) 
    save_summary_table_as_pdf(input_folder_path_abs, output_folder_path_abs) 
    os.remove(os.path.join(output_folder_path_abs, 'booktabs.sty')) 
    os.remove(os.path.join(output_folder_path_abs, 'geography.sty')) 
    os.remove(os.path.join(output_folder_path_abs, 'pdflscape.sty')) 
0

Nun ist eine Möglichkeit, Abschriften zu verwenden. Sie können df.to_html() verwenden. Dies konvertiert den Datenrahmen in eine HTML-Tabelle. Von dort können Sie den generierten HTML-Code in eine Markdown-Datei (.md) einfügen und ein Paket zum Konvertieren von Markdown in PDF verwenden. https://www.npmjs.com/package/markdown-pdf

Wäre das eine gute Alternative?

+0

Die erste Lösung, die ich geschrieben habe (df -> HTML -> pdf) auf meinem Rechner arbeiten, aber der Code kann nicht Führen Sie eine entfernte Maschine aus, auf der ich nicht die Rechte habe, PDFkit zu installieren. Ich denke, ich würde für makedown-pdf dasselbe sein. Deshalb muss ich die Abhängigkeiten so stark wie möglich begrenzen. –

+0

markdown-pdf ist nicht in der Lage, die PDF-Datei so zu skalieren, dass sie nur die Tabelle enthält – Chaoste

Verwandte Themen