【问题标题】:Numpy 2d and 1d array to latex bmatrixNumpy 2d 和 1d 数组到乳胶 bmatrix
【发布时间】:2013-06-16 01:00:41
【问题描述】:

我正在寻找一种将 numpy 数组迁移到 Latex bmatrix 的干净方法。它应该适用于二维数组和水平和垂直一维数组。

示例

A = array([[12, 5, 2],
           [20, 4, 8],
           [ 2, 4, 3],
           [ 7, 1,10]])

print A              #2d array
print A[0]           #horizontal array
print A[:,0, None]   #vertical array

array_to_bmatrix(A)
array_to_bmatrix(A[0])
array_to_bmatrix(A[:,0, None])

输出:

[[12  5  2]
 [20  4  8]
 [ 2  4  3]
 [ 7  1 10]]

[12  5  2]

[[12]
 [20]
 [ 2]
 [ 7]]

\begin{bmatrix} 
 12.000 & 5.000 & 2.000 & \\
 20.000 & 4.000 & 8.000 & \\
 2.000 & 4.000 & 3.000 & \\
 7.000 & 1.000 & 10.000 & \\
\end{bmatrix}

\begin{bmatrix} 
 12.000 & 5.000 & 2.000
\end{bmatrix}

\begin{bmatrix} 
 12.000 & \\
 20.000 & \\
 2.000 & \\
 7.000 & \\
\end{bmatrix}

解决方案的尝试

def array_to_bmatrix(array):
    begin = '\\begin{bmatrix} \n'
    data = ''
    for line in array:        
        if line.size == 1:
            data = data + ' %.3f &'%line
            data = data + r' \\'
            data = data + '\n'
            continue
        for element in line:
            data = data + ' %.3f &'%element

        data = data + r' \\'
        data = data + '\n'
    end = '\end{bmatrix}'
    print begin + data + end  

此解决方案适用于垂直和二维数组,但是它将水平数组输出为垂直数组。

array_to_bmatrix(A[0])

输出:

\begin{bmatrix} 
 12.000 & \\
 5.000 & \\
 2.000 & \\
\end{bmatrix}

【问题讨论】:

    标签: python numpy latex


    【解决方案1】:

    numpy 数组的__str__ 方法已经为您完成了大部分格式化工作。让我们利用它;

    import numpy as np
    
    def bmatrix(a):
        """Returns a LaTeX bmatrix
    
        :a: numpy array
        :returns: LaTeX bmatrix as a string
        """
        if len(a.shape) > 2:
            raise ValueError('bmatrix can at most display two dimensions')
        lines = str(a).replace('[', '').replace(']', '').splitlines()
        rv = [r'\begin{bmatrix}']
        rv += ['  ' + ' & '.join(l.split()) + r'\\' for l in lines]
        rv +=  [r'\end{bmatrix}']
        return '\n'.join(rv)
    
    A = np.array([[12, 5, 2], [20, 4, 8], [ 2, 4, 3], [ 7, 1, 10]])
    print bmatrix(A) + '\n'
    
    B = np.array([[1.2], [3.7], [0.2]])
    print bmatrix(B) + '\n'
    
    C = np.array([1.2, 9.3, 0.6, -2.1])
    print bmatrix(C) + '\n'
    

    这会返回:

    \begin{bmatrix}
      12 & 5 & 2\\
      20 & 4 & 8\\
      2 & 4 & 3\\
      7 & 1 & 10\\
    \end{bmatrix}
    
    \begin{bmatrix}
      1.2\\
      3.7\\
      0.2\\
    \end{bmatrix}
    
    \begin{bmatrix}
      1.2 & 9.3 & 0.6 & -2.1\\
    \end{bmatrix}
    

    【讨论】:

    • 这对于行长的矩阵有问题——它会在行的中间插入'\\',因为str(a)有一个最大的行宽。为了解决这个问题,我将您的bmatrix 函数中的str(a) 替换为np.array2string(a, max_line_width=np.infty),这样就可以使行成为全长。这也可以更好地控制其他字符串表示选择,例如精度和格式。
    【解决方案2】:

    试试array_to_latex (pip install)。正是出于这个原因,我才写了它。请在不足之处提供您的反馈。

    它具有默认值,但还允许您自定义格式(指数、小数位数)并处理复数,并且可以将结果“弹出”到剪贴板中(无需复制转储到屏幕上的文本)。

    github 存储库中的一些示例。 https://github.com/josephcslater/array_to_latex

    【讨论】:

    • 有没有办法保存字符串而不是使用您的工具打印它?我想将它与 IPython.display.Math 结合使用(如这里:stackoverflow.com/questions/48422762/…
    • 目前还没有——但做起来很简单。我现在完全被抨击了。在存储库上留个心眼——我会在几周后尝试解决这个问题。
    • @Jindra-Helci 这行得通-我忘记了。记录不够好。这可以在 a2l 的 github 页面上的 mybinder 示例中使用。 ` a = a2l.to_ltx(A, frmt = '{:.2f}', arraytype = 'array', mathform = True)`
    • 0.76 版本将更适合您。我添加了一个布尔值print_out,当它设置为 false 时,它​​将悄悄地返回输出中的乳胶。为您的使用/应用程序进行的其他重要清理。 pypi 上的自述文件是一篇落后的文章。检查 github 存储库上的文档,其中包含更新的示例以及 mybinder 笔记本,以及更新的示例。请让我知道这是否适合您。
    【解决方案3】:

    我对使用 Python 的打印输出不满意。矩阵可能太大,导致缠绕。 这是用于打印二维矩阵的 LaTeX 文本的代码。

    def bmatrix(a):
        text = r'$\left[\begin{array}{*{'
        text += str(len(a[0]))
        text += r'}c}'
        text += '\n'
        for x in range(len(a)):
            for y in range(len(a[x])):
                text += str(a[x][y])
                text += r' & '
            text = text[:-2]
            text += r'\\'
            text += '\n'
        text += r'\end{array}\right]$'
    
        print text
    

    这给了这个

    $\left[\begin{array}{*{16}c}
    2.01 & 0 & 0 & -1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & -1 & 0 & 0 \\
    0 & 2.01 & 0 & 0 & -1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & -1 & 0 \\
    0 & 0 & 2.01 & 0 & 0 & -1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & -1 \\
    -1 & 0 & 0 & 2.01 & 0 & 0 & -1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\
    0 & -1 & 0 & 0 & 2.01 & 0 & 0 & -1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\
    0 & 0 & -1 & 0 & 0 & 2.01 & 0 & 0 & -1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\
    0 & 0 & 0 & -1 & 0 & 0 & 2.01 & 0 & 0 & -1 & 0 & 0 & 0 & 0 & 0 & 0 \\
    0 & 0 & 0 & 0 & -1 & 0 & 0 & 2.01 & 0 & 0 & -1 & 0 & 0 & 0 & 0 & 0 \\
    0 & 0 & 0 & 0 & 0 & -1 & 0 & 0 & 2.01 & 0 & 0 & -1 & 0 & 0 & 0 & 0 \\
    0 & 0 & 0 & 0 & 0 & 0 & -1 & 0 & 0 & 2.01 & 0 & 0 & -1 & 0 & 0 & 0 \\
    0 & 0 & 0 & 0 & 0 & 0 & 0 & -1 & 0 & 0 & 2.01 & 0 & 0 & -1 & 0 & 0 \\
    0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & -1 & 0 & 0 & 2.01 & 0 & 0 & -1 & 0 \\
    0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & -1 & 0 & 0 & 2.01 & 0 & 0 & -1 \\
    -1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & -1 & 0 & 0 & 2.01 & 0 & 0 \\
    0 & -1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & -1 & 0 & 0 & 2.01 & 0 \\
    0 & 0 & -1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & -1 & 0 & 0 & 2.01 \\
    \end{array}\right]$
    

    【讨论】:

      【解决方案4】:

      进一步的答案,灵感来自 Roland Smith 的回答:

      def matToTex(a, roundn=2, matrixType = "b",rowVector = False):
          if type(a) != np.ndarray:
              raise ValueError("Input must be np array")
          if len(a.shape) > 2:
              raise ValueError("matrix can at most display two dimensions")
          if matrixType not in ["b","p"]:
              raise ValueError("matrix can be either type \"b\" or type \"p\"")
          if rowVector:
              if not (len(a.shape) != 1 or a.shape[0] != 1):
                  raise ValueError("Cannot rowVector this bad boi, it is not a vector!")
          lines = str(a).splitlines()
          ret = "\n\\begin{"+matrixType+"matrix}\n"
          for line in lines:
              line = re.sub("\s+",",",re.sub("\[|\]","",line).strip())
              nums = line.split(",");
              if roundn != -1:
                  nums = [str(round(float(num),roundn)) for num in nums]
              if rowVector:
                  ret += " \\\\\n".join(nums)
              else:
                  ret += " & ".join(nums)+" \\\\ \n"
          ret += "\n\\end{"+matrixType+"matrix}\n"
          ret = re.sub("(\-){0,1}0.[0]* ","0 ",ret)
          print(ret)
      

      【讨论】:

        【解决方案5】:

        另一个,灵感来自 Roland Smith 的回答 支持科学记数法格式

        def bmatrix(a):
            """Returns a LaTeX bmatrix
        
            :a: numpy array
            :returns: LaTeX bmatrix as a string
            """
            if len(a.shape) > 2:
                raise ValueError('bmatrix can at most display two dimensions')
            temp_string = np.array2string(a, formatter={'float_kind':lambda x: "{:.2e}".format(x)})
            lines = temp_string.replace('[', '').replace(']', '').splitlines()
            rv = [r'\begin{bmatrix}']
            rv += ['  ' + ' & '.join(l.split()) + r'\\' for l in lines]
            rv +=  [r'\end{bmatrix}']
            return '\n'.join(rv)
        

        结果:

        \begin{bmatrix}
          7.53e-04 & -2.93e-04 & 2.04e-04 & 5.30e-05 & 1.84e-01 & -2.43e-05\\
          -2.93e-04 & 1.19e-01 & 2.96e-01 & 2.19e-01 & 1.98e+01 & 8.61e-03\\
          2.04e-04 & 2.96e-01 & 9.60e-01 & 7.42e-01 & 4.03e+01 & 2.45e-02\\
          5.30e-05 & 2.19e-01 & 7.42e-01 & 6.49e-01 & 2.82e+01 & 1.71e-02\\
          1.84e-01 & 1.98e+01 & 4.03e+01 & 2.82e+01 & 5.75e+03 & 1.61e+00\\
          -2.43e-05 & 8.61e-03 & 2.45e-02 & 1.71e-02 & 1.61e+00 & 7.04e-03\\
        \end{bmatrix}
        

        【讨论】:

          【解决方案6】:

          当你这样做时:

              for line in array:
          

          您正在迭代array 的第一个维度。当数组是一维时,您最终会迭代这些值。在进行此迭代之前,您需要确保 array 确实是二维的。一种方法是通过numpy.atleast_2d 传递参数:

          import numpy as np
          
          def array_to_bmatrix(array):
              array = np.atleast_2d(array)
              begin = '\\begin{bmatrix} \n'
              data = ''
              for line in array:
          

          等等

          【讨论】:

            【解决方案7】:

            我已尝试制定一个全面的解决方案,以便个人无需编写甚至最小的脚本即可完成。我为浮点数、格式化、复杂和 Pandas 数组提供了灵活性。请使用并向 (array_to_latex)[https://pypi.org/project/array-to-latex/] 提供反馈。

            【讨论】:

              【解决方案8】:

              此外,对于之前的答案,您可以通过这种方式从数组中生成乳胶

              from IPython.display import *
              from numpy import *
              A = array([[12, 5, 2],
                         [20, 4, 8],
                         [ 2, 4, 3],
                         [ 7, 1,10]])
              list=A
              
              str1 ='$$' +'\\begin{bmatrix}'+ '&\\\\'.join(str(e) for e in list)+ '\\end{bmatrix}'+'$$'
              print(str1 )
              str1 = str1.replace('[', ' ')
              str1 = str1.replace(']', ' ')
              
              display(Latex(str1))
              

              【讨论】:

                【解决方案9】:

                另一种选择是使用 sympy:首先将数组转换为 sympy.Matrix,然后使用 sympy.latex 函数。

                【讨论】:

                  猜你喜欢
                  • 2021-01-28
                  • 1970-01-01
                  • 1970-01-01
                  • 2017-06-18
                  • 2021-10-12
                  • 2017-06-18
                  • 1970-01-01
                  • 1970-01-01
                  • 2022-01-17
                  相关资源
                  最近更新 更多