在Python中将字符串转换为乳胶表格式

时间:2015-06-14 17:03:02

标签: python latex scikit-learn

我有使用Sklearn的机器学习算法的以下性能报告:

>>> from sklearn.metrics import classification_report
>>> y_true = [0, 1, 2, 2, 2]
>>> y_pred = [0, 0, 2, 2, 1]
>>> target_names = ['class 0', 'class 1', 'class 2']
>>> print(classification_report(y_true, y_pred, target_names=target_names))
             precision    recall  f1-score   support

    class 0       0.50      1.00      0.67         1
    class 1       0.00      0.00      0.00         1
    class 2       1.00      0.67      0.80         3

avg / total       0.70      0.60      0.61         5

我使用classification_reportfile.write(report)保存为文本文件,但我想将其保存为TEX表格式,如下所示:

\begin{table}[htbp]
  \centering
  \caption{Add caption}
    \begin{tabular}{rrrrr}
    \toprule
          & precision & recall & f1-score & support \\
    \midrule
          &       &       &       &  \\
    class 0 & 0.5   & 1     & 0.67  & 1 \\
    class 1 & 0     & 0     & 0     & 1 \\
    class 2 & 1     & 0.67  & 0.8   & 3 \\
          &       &       &       &  \\
    avg/total & 0.7   & 0.6   & 0.61  & 5 \\
    \bottomrule
    \end{tabular}%
  \label{tab:addlabel}%
\end{table}%

有关如何实现这一目标的任何建议?谢谢!

1 个答案:

答案 0 :(得分:0)

表格页眉和页脚只是文字,所以我会跳过这些。

获取classification_report的输出,并将其拆分为str.splitlines()行。

In [7]: rep = """             precision    recall  f1-score   support
   ...: 
   ...:     class 0       0.50      1.00      0.67         1
   ...:     class 1       0.00      0.00      0.00         1
   ...:     class 2       1.00      0.67      0.80         3
   ...: 
   ...: avg / total       0.70      0.60      0.61         5"""

In [8]: rep.splitlines()
Out[8]: 
['             precision    recall  f1-score   support',
 '',
 '    class 0       0.50      1.00      0.67         1',
 '    class 1       0.00      0.00      0.00         1',
 '    class 2       1.00      0.67      0.80         3',
 '',
 'avg / total       0.70      0.60      0.61         5']

由于您知道第一行和最后两行包含的内容,因此您可以将格式化工作集中在其余行上。

In [9]: lines = rep.splitlines()

In [10]: lines[2:-2]
Out[10]: 
['    class 0       0.50      1.00      0.67         1',
 '    class 1       0.00      0.00      0.00         1',
 '    class 2       1.00      0.67      0.80         3']

In [11]: cl = lines[2:-2]

In [19]: [ln.replace('class ', '').split() for ln in cl]
Out[19]: 
[['0', '0.50', '1.00', '0.67', '1'],
 ['1', '0.00', '0.00', '0.00', '1'],
 ['2', '1.00', '0.67', '0.80', '3']]

In [20]: cl = [ln.replace('class ', '').split() for ln in cl]

In [23]: for ln in cl:
    print('class ' + ' & '.join(ln) + r'\\')
   ....:     
class 0 & 0.50 & 1.00 & 0.67 & 1\\
class 1 & 0.00 & 0.00 & 0.00 & 1\\
class 2 & 1.00 & 0.67 & 0.80 & 3\\

avg行的处理方式大致相同。

In [25]: last = lines[-1]

In [29]: last[11:].split()
Out[29]: ['0.70', '0.60', '0.61', '5']

In [30]: numbers = last[11:].split()

In [31]: print('avg / total & ' + ' & '.join(numbers) + r'\\')
avg / total & 0.70 & 0.60 & 0.61 & 5\\

我建议跳过空行,特别是因为您已经使用了booktabs包中的标尺。

<强>替代

如果有一种方法可以逐行地从sklearn获取数据,您可能需要查看我编写的简单latable Python模块。