我爲此寫了我自己的基於mako
的模板方案。我認爲這實際上是一個非常簡單的工作流程,如果你承諾爲自己闖過一次。在那之後,你開始看到模板化所需格式的元數據,所以它可以從代碼中分解出來(並且不代表第三方依賴)是解決它的一個很好的方法。
這是我想出的工作流程。
編寫接受您的數據幀作爲參數(可能還有其他參數),並把它轉換成你想要的(如下所示)TeX的格式.mako模板。創建一個包裝類(我稱之爲to_tex
),它使得你需要的API(例如,你可以傳遞你的數據對象,並在內部處理對mako
渲染命令的調用)。
在包裝類中,決定您希望如何輸出。將TeX代碼打印到屏幕上?使用一個子進程來實際編譯成PDF?
在我的情況,我正在生成一份研究報告的初步結果,並需要格式化表格與嵌套列名等複雜的雙排序結構這是一個什麼樣的表的一個看起來像一個例子:
![Example output from templated TeX tool](https://i.stack.imgur.com/NXTev.png)
下面是該灰鯖模板(警告,毛):
<%page args="df, table_title, group_var, sort_var"/>
<%
"""
Template for country/industry two-panel double sorts TeX table.
Inputs:
-------
df: pandas DataFrame
Must be 17 x 12 and have rows and columns that positionally
correspond to the entries of the table.
table_title: string
String used for the title of the table.
group_var: string
String naming the grouping variable for the horizontal sorts.
Should be 'Country' or 'Industry'.
sort_var: string (raw)
String naming the variable that is being sorted, e.g.
"beta" or "ivol". Note that if you want the symbol to
be rendered as a TeX symbol, then pass a raw Python
string as the arg and include the needed TeX markup in
the passed string. If the string isn't raw, some of the
TeX markup might be interpreted as special characters.
Returns:
--------
When used with mako.template.Template.render, will produce
a raw TeX string that can be rendered into a PDF containing
the specified data.
Author:
-------
Ely M. Spears, 05/21/2013
"""
# Python imports and helper function definitions.
import numpy as np
def format_helper(x):
return str(np.round(x,2))
%>
<%text>
\documentclass[10pt]{article}
\usepackage[top=1in, bottom=1in, left=1in, right=1in]{geometry}
\usepackage{array}
\newcolumntype{L}[1]{>{\raggedright\let\newline\\\arraybackslash\hspace{0pt}}m{#1}}
\newcolumntype{C}[1]{>{\centering\let\newline\\\arraybackslash\hspace{0pt}}m{#1}}
\setlength{\parskip}{1em}
\setlength{\parindent}{0in}
\renewcommand*\arraystretch{1.5}
\author{Ely Spears}
\begin{document}
\begin{table} \caption{</%text>${table_title}<%text>}
\begin{center}
\begin{tabular}{ | p{2.5cm} c c c c c p{1cm} c c c c c c p{1cm} |}
\hline
& \multicolumn{6}{c}{CAPM $\beta$} & \multicolumn{6}{c}{CAPM $\alpha$ (\%p.a.)} & \\
\cline{2-7} \cline{9-14}
& \multicolumn{6}{c}{</%text>${group_var}<%text> </%text>${sort_var}<%text> is:} & \multicolumn{6}{c}{</%text>${group_var}<%text> </%text>${sort_var}<%text> is:} & \\
Stock </%text>${sort_var}<%text> is: & Low & 2 & 3 & 4 & High & Low - High & & Low & 2 & 3 & 4 & High & Low - High \\
\hline
\multicolumn{4}{|l}{Panel A. Point estimates} & & & & & & & & & & \\
\hline
Low & </%text>${' & '.join(df.ix[0].map(format_helper).values[0:6])}<%text> & & </%text>${' & '.join(df.ix[0].map(format_helper).values[6:])}<%text> \\
2 & </%text>${' & '.join(df.ix[1].map(format_helper).values[0:6])}<%text> & & </%text>${' & '.join(df.ix[1].map(format_helper).values[6:])}<%text> \\
3 & </%text>${' & '.join(df.ix[2].map(format_helper).values[0:6])}<%text> & & </%text>${' & '.join(df.ix[2].map(format_helper).values[6:])}<%text> \\
4 & </%text>${' & '.join(df.ix[3].map(format_helper).values[0:6])}<%text> & & </%text>${' & '.join(df.ix[3].map(format_helper).values[6:])}<%text> \\
High & </%text>${' & '.join(df.ix[4].map(format_helper).values[0:6])}<%text> & & </%text>${' & '.join(df.ix[4].map(format_helper).values[6:])}<%text> \\
Low - High & </%text>${' & '.join(df.ix[5].map(format_helper).values[0:5])}<%text> & & & </%text>${' & '.join(df.ix[5].map(format_helper).values[6:11])}<%text> & \\
\multicolumn{6}{|l}{</%text>${group_var}<%text> effect (average of Low - High \underline{column})}
& </%text>${format_helper(df.ix[6,5])}<%text> & & & & & & & </%text>${format_helper(df.ix[6,11])}<%text> \\
\multicolumn{6}{|l}{Within-</%text>${group_var}<%text> effect (average of Low - High \underline{row})}
& </%text>${format_helper(df.ix[7,5])}<%text> & & & & & & & </%text>${format_helper(df.ix[7,11])}<%text> \\
\multicolumn{13}{|l}{Total effect} & </%text>${format_helper(df.ix[8,11])}<%text> \\
\hline
\multicolumn{4}{|l}{Panel B. t-statistics} & & & & & & & & & & \\
\hline
Low & </%text>${' & '.join(df.ix[9].map(format_helper).values[0:6])}<%text> & & </%text>${' & '.join(df.ix[9].map(format_helper).values[6:])}<%text> \\
2 & </%text>${' & '.join(df.ix[10].map(format_helper).values[0:6])}<%text> & & </%text>${' & '.join(df.ix[10].map(format_helper).values[6:])}<%text> \\
3 & </%text>${' & '.join(df.ix[11].map(format_helper).values[0:6])}<%text> & & </%text>${' & '.join(df.ix[11].map(format_helper).values[6:])}<%text> \\
4 & </%text>${' & '.join(df.ix[12].map(format_helper).values[0:6])}<%text> & & </%text>${' & '.join(df.ix[12].map(format_helper).values[6:])}<%text> \\
High & </%text>${' & '.join(df.ix[13].map(format_helper).values[0:6])}<%text> & & </%text>${' & '.join(df.ix[13].map(format_helper).values[6:])}<%text> \\
Low - High & </%text>${' & '.join(df.ix[14].map(format_helper).values[0:5])}<%text> & & & </%text>${' & '.join(df.ix[14].map(format_helper).values[6:11])}<%text> & \\
\multicolumn{6}{|l}{</%text>${group_var}<%text> effect (average of Low - High \underline{column})}
& </%text>${format_helper(df.ix[15,5])}<%text> & & & & & & & </%text>${format_helper(df.ix[15,11])}<%text> \\
\multicolumn{6}{|l}{Within-</%text>${group_var}<%text> effect (average of Low - High \underline{row})}
& </%text>${format_helper(df.ix[16,5])}<%text> & & & & & & & </%text>${format_helper(df.ix[16,11])}<%text> \\
\hline
\end{tabular}
\end{center}
\end{table}
\end{document}
</%text>
我的包裝to_tex.py
看起來像這樣(用例在if __name__ == "__main__"
部分使用):
"""
to_tex.py
Class for handling strings of TeX code and producing the
rendered PDF via PDF LaTeX. Assumes ability to call PDFLaTeX
via the operating system.
"""
class to_tex(object):
"""
Publishes a TeX string to a PDF rendering with pdflatex.
"""
def __init__(self, tex_string, tex_file, display=False):
"""
Publish a string to a .tex file, which will be
rendered into a .pdf file via pdflatex.
"""
self.tex_string = tex_string
self.tex_file = tex_file
self.__to_tex_file()
self.__to_pdf_file(display)
print "Render status:", self.render_status
def __to_tex_file(self):
"""
Writes a tex string to a file.
"""
with open(self.tex_file, 'w') as t_file:
t_file.write(self.tex_string)
def __to_pdf_file(self, display=False):
"""
Compile a tex file to a pdf file with the
same file path and name.
"""
try:
import os
from subprocess import Popen
proc = Popen(["pdflatex", "-output-directory", os.path.dirname(self.tex_file), self.tex_file])
proc.communicate()
self.render_status = "success"
except Exception as e:
self.render_status = str(e)
# Launch a display of the pdf if requested.
if (self.render_status == "success") and display:
try:
proc = Popen(["evince", self.tex_file.replace(".tex", ".pdf")])
proc.communicate()
except:
pass
if __name__ == "__main__":
from mako.template import Template
template_file = "path/to/template.mako"
t = Template(filename=template_file)
tex_str = t.render(arg1="arg1", ...)
tex_wrapper = to_tex(tex_str,)
我的選擇是直接泵TeX的字符串pdflatex
並作爲選項顯示它。
的實際使用這一個數據幀一小段代碼是在這裏:
# Assume calculation work is done prior to this ...
all_beta = pandas.concat([beta_df, beta_tstat_df], axis=0)
all_alpha = pandas.concat([alpha_df, alpha_tstat_df], axis=0)
all_df = pandas.concat([all_beta, all_alpha], axis=1)
# Render result in TeX
tex_mako = "/my_project/templates/mako/two_panel_double_sort_table.mako"
tex_file = "/my_project/some_tex_file_name.tex"
from mako.template import Template
t = Template(filename=tex_mako)
tex_str = t.render(all_df, table_title, group_var, tex_risk_name)
import my_project.to_tex as to_tex
tex_obj = to_tex.to_tex(tex_str, tex_file)
您不需要創建自定義類以將formater添加到現有類中:http:// nbvi ewer.ipython.org/github/ipython/ipython/blob/master/examples/notebooks/Custom%20Display%20Logic.ipynb#Adding-IPython-display-support-to-existing-objects,並且沒有熊貓沒有辦法制作來自表IIRC的乳膠。 – Matt
我在這裏做了類似的事情,但我對解決方案不滿意。 http://stackoverflow.com/questions/24574976/save-the-out-table-of-a-pandas-dataframe-as-a-figure?lq=1 – Keith