如何打印完整的NumPy数组,而不截断?

875

我打印一个 numpy 数组时,得到的是截断后的表示,但我需要完整的数组。

>>> numpy.arange(10000)
array([   0,    1,    2, ..., 9997, 9998, 9999])

>>> numpy.arange(10000).reshape(250,40)
array([[   0,    1,    2, ...,   37,   38,   39],
       [  40,   41,   42, ...,   77,   78,   79],
       [  80,   81,   82, ...,  117,  118,  119],
       ..., 
       [9880, 9881, 9882, ..., 9917, 9918, 9919],
       [9920, 9921, 9922, ..., 9957, 9958, 9959],
       [9960, 9961, 9962, ..., 9997, 9998, 9999]])

36
有没有一种方法可以“一次性”完成它?也就是说,打印出完整的输出结果一次,但不在脚本的其他时间打印输出结果? - tumultous_rooster
4
@Matt O'Brien,请参考ZSG在下面的回答。 - user2398029
7
你能否将采纳的答案更改为推荐使用 np.inf 的答案?np.nan'nan' 只是碰巧起作用,而且['nan'在Python 3中甚至都不起作用](http://ideone.com/tjyGhX),因为它们改变了混合类型比较实现所依赖的 threshold='nan'`。 - user2357112
1
threshold=np.nan 而不是 'nan' 取决于另一个巧合,即数组打印逻辑使用 a.size > _summaryThreshold 将数组大小与阈值进行比较。对于 _summaryThreshold=np.nan,其始终返回 False。如果比较是 a.size <= _summaryThreshold,则测试是否应完全打印数组而不是测试是否应该进行汇总,则此阈值将触发所有数组的汇总。 - user2357112
8
一种“一次性”的做法是:如果你有一个numpy.array tmp,只需使用list(tmp)。其他格式不同的选项包括tmp.tolist(),或者为了更多控制使用print("\n".join(str(x) for x in tmp)) - travc
显示剩余3条评论
23个回答

951

7
如果您只想打印 numpy 数组一次,不幸的是,这种解决方案的缺点是需要在打印后重置此配置更改。 - Trevor Boyd Smith
3
@TrevorBoydSmith,你知道如何在打印后重置这个参数吗? - ColinMac
2
@ColinMac 请参考 https://dev59.com/q3I-5IYBdhLWcg3wKVA9#24542498,其中他保存设置,执行操作,然后恢复设置。 - Trevor Boyd Smith
3
如何将它恢复到正常状态? - Gulzar
5
@Gulzar 使用: numpy.set_printoptions(threshold=False)。该代码用于设置NumPy数组的打印选项,其中threshold参数默认为1000,当数组元素数量大于或等于该值时,数组将被截断并以省略号表示。通过将threshold参数设置为False,可以禁用这种截断行为。 - Rahul Vishwakarma
显示剩余3条评论

307
import numpy as np
np.set_printoptions(threshold=np.inf)

我建议使用np.inf而不是其他人建议的np.nan。它们都可以用于您的目的,但是通过将阈值设置为“无穷大”,每个读取您代码的人都能明确您的意思。对我来说,“不是数字”的阈值似乎有点模糊。


23
这个的逆操作是什么?如何回到以前的设置(带有点)? - Karlo
17
默认数量为1000,因此np.set_printoptions(threshold=1000)将恢复默认行为。但是你可以将此阈值设置得低或高。np.set_printoptions(threshold=np.inf)仅仅改变了在打印出来之前一个数组的最大大小,在被截断之前,它会被截断到无穷大,这样无论有多大都不会被截断。如果你将阈值设置为任何实数,则那将是最大大小。 - PaulMag
9
这不仅更加清晰,而且更加健壮。对于np.infnp.nan或者'nan'没有任何特殊处理。无论你放什么在那里,NumPy都将使用一个简单的>来比较数组的大小和你的阈值。np.nan之所以能够工作,只是因为它是a.size > _summaryThreshold而不是a.size <= _summaryThreshold,并且np.nan返回所有>/</>=/<=比较的False'nan'只因为Python 2的混合类型比较逻辑的脆弱实现细节而碰巧工作;在Python 3上它完全失效。 - user2357112
2
使用sys.maxsize,因为该值被记录为整数。 - mattip
7
为了恰当回答 @Karlo 的问题,请注意打印选项阈值的初始值可以在 np.get_printoptions()['threshold'] 中找到。您可以在设置阈值之前存储此值,然后在之后恢复它(或者像其他答案建议的那样使用 with 块)。 - Ninjakannon

225

临时设置

您可以使用printoptions上下文管理器:

with numpy.printoptions(threshold=numpy.inf):
    print(arr)

(当然,如果您导入numpy的方式是np,则将numpy替换为np。)

使用上下文管理器(with块)确保在上下文管理器完成后,打印选项将恢复为块开始之前的设置。它确保设置是临时的,并且仅适用于块内的代码。

有关上下文管理器及其支持的其他参数的详细信息,请参见numpy.printoptions文档。它在NumPy 1.15中引入(发布于2018-07-23)。


172

前面的回答是正确的,但作为一个更弱的选择,你可以将其转换为列表:

>>> numpy.arange(100).reshape(25,4).tolist()

[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14, 15], [16, 17, 18, 19], [20, 21,
22, 23], [24, 25, 26, 27], [28, 29, 30, 31], [32, 33, 34, 35], [36, 37, 38, 39], [40, 41,
42, 43], [44, 45, 46, 47], [48, 49, 50, 51], [52, 53, 54, 55], [56, 57, 58, 59], [60, 61,
62, 63], [64, 65, 66, 67], [68, 69, 70, 71], [72, 73, 74, 75], [76, 77, 78, 79], [80, 81,
82, 83], [84, 85, 86, 87], [88, 89, 90, 91], [92, 93, 94, 95], [96, 97, 98, 99]]

26
这似乎是在打印语句中查看完整数组的最佳方法。 - Aaron Bramson
@AaronBramson 我同意... 当你只需要一个打印语句时,这样做会减少错误的可能性(与更改配置、打印、重置配置需要三行代码相比)。 - Trevor Boyd Smith
我喜欢这个打印逗号分隔符的功能。 - ObviousChild
这个解决方案对于整数非常好,但对于双精度浮点数不太好。 - bfris

50

这里有一种一次性的方法来做到这一点,如果您不想更改默认设置,这非常有用:

def fullprint(*args, **kwargs):
  from pprint import pprint
  import numpy
  opt = numpy.get_printoptions()
  numpy.set_printoptions(threshold=numpy.inf)
  pprint(*args, **kwargs)
  numpy.set_printoptions(**opt)

20
看起来这里可以使用上下文管理器,这样你就可以使用“with fullprint”语句。 - Paul Price

47
这听起来像是你在使用numpy。
如果是这样的话,你可以添加:
import numpy as np
import sys
np.set_printoptions(threshold=sys.maxsize)

那将禁用角落打印。有关更多信息,请参阅此NumPy教程

16
数值错误:阈值必须是数字且非NAN,请尝试使用sys.maxsize来获得未截断的表示。 - Eric
1
是的,官方Numpy教程中的那一部分是错误的。 - aderchox

35

遵循Paul Price的建议,使用上下文管理器。

import numpy as np


class fullprint:
    'context manager for printing full numpy arrays'

    def __init__(self, **kwargs):
        kwargs.setdefault('threshold', np.inf)
        self.opt = kwargs

    def __enter__(self):
        self._opt = np.get_printoptions()
        np.set_printoptions(**self.opt)

    def __exit__(self, type, value, traceback):
        np.set_printoptions(**self._opt)


if __name__ == '__main__': 
    a = np.arange(1001)

    with fullprint():
        print(a)

    print(a)

    with fullprint(threshold=None, edgeitems=10):
        print(a)

7
这个上下文管理器已经内置于numpy 1.15中,感谢https://github.com/numpy/numpy/pull/10406的支持,名称为`np.printoptions`。 - Eric

17

numpy.savetxt

numpy.savetxt(sys.stdout, numpy.arange(10000))

或者如果你需要一个字符串:

import StringIO
sio = StringIO.StringIO()
numpy.savetxt(sio, numpy.arange(10000))
s = sio.getvalue()
print s

默认输出格式为:

0.000000000000000000e+00
1.000000000000000000e+00
2.000000000000000000e+00
3.000000000000000000e+00
...

而且它可以通过其他参数进行配置。

要特别注意的是,这也不显示方括号,并允许进行很多自定义,如此处所述:如何在不使用方括号的情况下打印Numpy数组?

在Python 2.7.12和numpy 1.11.1上进行了测试。


1
这种方法的小缺点是它只适用于一维和二维数组。 - Fnord
@Fnord,感谢您提供这些信息,如果您找到解决方法,请告诉我! - Ciro Santilli OurBigBook.com

13
这是neok的回答稍作修改(去掉了传递额外参数给set_printoptions的选项)。
它展示了如何使用contextlib.contextmanager轻松创建这样一个上下文管理器,代码行数更少:
import numpy as np
from contextlib import contextmanager

@contextmanager
def show_complete_array():
    oldoptions = np.get_printoptions()
    np.set_printoptions(threshold=np.inf)
    try:
        yield
    finally:
        np.set_printoptions(**oldoptions)

在你的代码中,可以像这样使用:

a = np.arange(1001)

print(a)      # shows the truncated array

with show_complete_array():
    print(a)  # shows the complete array

print(a)      # shows the truncated array (again)

1
在上下文管理器中,您应该始终在 yield 周围放置 try / finally,以便无论如何都进行清理。 - Eric
1
@Eric 确实。感谢您的有益评论,我已更新答案。 - MSeifert
在1.15中,这可以拼写为 with np.printoptions(threshold=np.inf): - Eric

13
with np.printoptions(edgeitems=50):
    print(x)

将50更改为您想要查看的行数

来源:这里


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接