【问题标题】:maximum allowed dimention exceeded超出最大允许尺寸
【发布时间】:2019-01-13 16:28:18
【问题描述】:

我正在尝试用 pi 和地球在海平面的引力常数转换为二进制来制作一幅基于宇宙质量的画。我已经计算过了,我有正确的尺寸,它应该只小于 1 兆字节的内存,但我遇到了最大允许尺寸超出值错误。

代码如下:

import matplotlib.pyplot as plt
import matplotlib.cm as cm
import numpy as np

boshi = 123456789098765432135790864234579086542098765432135321 # universal mass

genesis = boshi ** 31467 # padding

artifice = np.binary_repr(genesis) # formatting

A = int(artifice) 

D = np.array(A).reshape(A, (1348, 4117))

plt.imsave('hello_world.png', D, cmap=cm.gray) # save image

我一直在D = np.array... 遇到错误,也许我的重塑太大但它只比 4k 大一点。似乎这对于 gpu 增强的 colab 应该没问题。也不会在我的家用机器上运行,但出现相同的错误。这会用更多的内存来解决吗?

【问题讨论】:

  • 这是偷懒吗?这是我在 python 中的第一个代码,我已经研究了几个月。
  • 不用担心被否决。几乎每个初学者的问题都会无缘无故地得到一个。我越看你的问题,我就越喜欢它。我知道你已经选择了一个答案,但我一直在玩你在这里所做的事情。如果我能找到更好的方法,我会继续发布更新。
  • 所以为了清楚起见,您正在尝试获取一个包含 1348 行和 4117 列的 0 和 1 数组?
  • 感谢物理学家,我认为您的回答更能说明我的目标。雅 1348 行和 4117 列。我认为它会产生组织较少的领域。您也可以使用 cm.coolwarm 代替 gray 来获得红色和蓝色
  • 你可以,但它没有多大帮助,因为你只有两个可能的值。我也会为此发表一个建议。

标签: python arrays image hardware reshape


【解决方案1】:

让它发挥作用

问题在于artifice = np.binary_repr(genesis) 创建了一个字符串。该字符串由1348 * 4117 = 5549716 数字组成,它们都是零和一。如果将字符串转换为 python 整数 A = int(artifice),您将 (A) 等待很长时间,并且 (B) 得到一个不可迭代的对象。您使用np.array(A) 创建的数组将只有一个元素。

好消息是,您可以完全绕过耗时的步骤,因为字符串 artifice 已经是可迭代的:

D = np.array(list(artifice), dtype=np.uint8).reshape(1348, 4117)

步骤list(artifice) 需要几秒钟,因为它必须拆分字符串,但其他一切都应该很快。

使用plt.imsave('hello_world.png', D, cmap=cm.gray),从那里轻松绘图:

颜色图

您可以在保存图像时轻松地将颜色图更改为coolwarm 或您想要的任何内容。请记住,您的图像是二进制的,因此实际上只有两个值很重要:

plt.imsave('hello_world2.png', D, cmap=cm.coolwarm)

探索

您有机会在这里为您的图像添加大量色彩。通常,PNG 是 8 位的。例如,您可以从中获取字节来构造图像,而不是将genesis 转换为位。您还可以使用半字节(半字节)来构建具有 16 种颜色的索引图像。通过一点填充,您甚至可以确保您拥有三个数据点的倍数,并以多种方式创建全彩色 RGB 图像。我不会介绍更复杂的选项,但我想探索从字节制作简单的图像。

5549716 位是693715 = 5 * 11 * 12613 字节(有四个前导零位)。这是一个非常讨厌的分解,导致图像大小为 55x12613,所以让我们删除上面的半字节:虽然 693716 的分解与 693715 的一样糟糕,693714 很好地分解为 597 * 1162

您可以使用自己的to_bytes 方法将整数转换为字节数组:

from math import ceil

byte_genesis = genesis.to_bytes(ceil(genesis.bit_length() / 8), 'big')

我使用内置 ceil 而不是 np.ceil 的原因是它返回一个整数而不是浮点数。

转换大整数非常快,因为bytes 对象可以直接访问整数的数据:即使它进行复制,它实际上也不会进行任何处理。它甚至可以共享缓冲区,因为bytesint 名义上是不可变的。同样,您可以从bytes 创建一个numpy 数组,作为使用np.frombuffer 的同一内存位置的视图:

img = np.frombuffer(byte_genesis, dtype=np.uint8)[1:].reshape(597, 1162)

[1:] 是切断前半字节所必需的,因为bytes_genesis 必须足够大以容纳整个genesis。你也可以在bytes 那边砍掉:

img = np.frombuffer(byte_genesis[1:], dtype=np.uint8).reshape(597, 1162)

结果是相同的。这是图片的样子:

plt.imsave('hello_world3.png', img, cmap=cm.viridis)

结果太大无法上传(因为不是二值图),但这里是随机抽取的样本:

我不确定这是否是您正在寻找的美学内容,但希望这为您提供了一个开始研究如何将非常大的数字转换为数据缓冲区的地方。

更多选项,因为这很有趣

我想在这里看看使用半字节而不是字节,因为这样可以让每个像素有 16 种颜色,像素数量是原来的两倍。您可以从

开始获得 1162x1194 的图像
temp = np.frombuffer(byte_genesis, dtype=np.uint8)[1:]

这是一种解压方式:

img = np.empty((1162, 1194), dtype=np.uint8)
img.ravel()[::2] = np.bitwise_and(temp >> 4, 0x0F)
img.ravel()[1::2] = np.bitwise_and(temp, 0x0F)

使用像 jet 这样的颜色图,您会得到:

plt.imsave('hello_world4.png', img, cmap=cm.jet)

另一种选择,从某种意义上说是相反的方向)是根本不使用颜色图。相反,您可以将您的空间除以三倍并在 RGB 空间中生成您自己的颜色。幸运的是,693714 的主要因素之一是3。因此,您可以获得 398x581 的图像 (693714 == 3 * 398 * 581)。您如何解释数据甚至比平时更取决于您。

在我继续之前的补充说明

使用黑白二值图像,您可以控制图像的颜色、大小和方向。使用 8 位数据,您可以控制位的采样方式(8 或更少,如 4 位示例)、解释的字节顺序、颜色图和图像大小。使用全彩色,您可以将每个三元组视为单独的颜色,将整个数据集视为三个连续的颜色平面,甚至可以执行类似将Bayer filter 应用于数组的操作。除了大小、排序、每个样本的位数等其他选项之外。

下面将暂时显示三色和三色平面选项。

全彩图片

要将每组 3 个连续字节视为 RGB 三元组,您可以执行以下操作:

img = temp.reshape(398, 581, 3)
plt.imsave('hello_world5.png', img)

请注意,在这种情况下没有颜色图。

将数据解释为三个颜色平面需要一个额外的步骤,因为plt.imsave 期望最后一个维度的大小为 3。np.rollaxis 是一个很好的工具:

img = np.rollaxis(temp.reshape(3, 398, 581), 0, 3)
plt.imsave('hello_world6.png', img)

【讨论】:

  • @DanteBonfatti。我同意。这是一个整洁的。
  • 我已经复制了您的电子邮件。我建议您从这个非常公开的论坛中删除它。
【解决方案2】:

我无法重现您的问题,因为A = int(artifice) 行一直占用。我将其替换为 ,for 循环以自行转换每个数字。然后代码运行并生成了所需的图像。

import matplotlib.pyplot as plt
import matplotlib.cm as cm
import numpy as np

boshi = 123456789098765432135790864234579086542098765432135321
genesis = boshi ** 31467
artifice = np.binary_repr(genesis)

D = np.zeros((1348, 4117), dtype=int)
for i, val in enumerate(D):
    D[i] = int(artifice[i])

plt.imsave('hello_world.png', D, cmap=cm.gray)

【讨论】:

  • 为什么投反对票?此代码可以工作并生成 OP 想要的图像,甚至比原始版本更快。请说明你的意图。
  • 这根本没有解决 OP 的明显错字。
  • 即使我的回答是解决 OP 问题的有效解决方案。因此,这种反对票绝对没有道理。
  • 好的。够公平
  • maxpowers 不是我想要的,但它真的很酷。我脑海中浮现出我需要继续寻找的画面。
猜你喜欢
  • 1970-01-01
  • 2012-10-21
  • 2012-08-18
  • 1970-01-01
  • 2010-09-30
  • 1970-01-01
  • 2020-10-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多