【问题标题】:Why can't I reshape numpy string arrays and ctype arrays?为什么我不能重塑 numpy 字符串数组和 ctype 数组?
【发布时间】:2018-08-02 17:39:14
【问题描述】:

也许有一种我想念的方法。长话短说,我需要一个大型文本文件的共享内存访问,只读。当然,使用字符串是必要的。所以我正在尝试这样做:

import numpy
from multiprocessing import Pool, RawArray

if __name__ == '__main__':
    with open('test.txt', 'r') as fin:
        raw = fin.readlines()
    X_shape = (len(raw), 70) # 70 characters per line should be sufficient for my needs
    X = RawArray('c', X_shape[0] * X_shape[1])
    X_np = np.frombuffer(X).reshape(X_shape)
    numpy.copyto(X_np, raw)

这不起作用,它在倒数第二行失败,输出如下:

ValueError: cannot reshape array of size 102242175 into shape (11684820,70)

作为参考,文件示例的长度为 11684820 行。并且 11684820 * 70 绝对不会是数组声称其大小的字符数。

显然我一定做错了什么,但这是我认为使用文本文件的文本文件输入多处理一些 CPU 绑定计算可行的唯一方法,这些文本文件输入在低端有几百兆字节,在高端大约 6GB结束。

是否有解决方法,或者可能是更正确的方法,以便我可以在共享内存中拥有大量字符串,我可以使用 python 代码处理这些字符串?谢谢。

【问题讨论】:

  • @DYZ: readlines 返回一个行列表,所以len(raw) 应该是行数。
  • @user2357112 糟糕,我的错。

标签: python arrays numpy reshape array-broadcasting


【解决方案1】:

numpy.frombuffer 需要一个明确的 dtype,否则它将默认为 dtype=float。此外,一个 11684820x70 的 uint8 数组或 1 个字符的字节串与长度为 11684820 的 70 个字符的字节串数组不同,因此请记住这一点。

对于 11684820x70 阵列,您要求的形状,但可能不是您需要的:

X_np = np.frombuffer(X, dtype=np.uint8).reshape(X_shape)

对于长度为 11684820 的 dtype S70 数组(最大长度为 70 的以空字符结尾的字节串,在 NumPy 文档中描述为“不推荐”):

X_np = np.frombuffer(X, dtype='S70')

对于 dtype U70 的长度为 11684820 的数组(最大长度为 70 的以 null 结尾的 Unicode 字符串),您需要更大的缓冲区(每个字符 4 个字节),然后

X_np = np.frombuffer(X, dtype='U70')

【讨论】:

  • 这点很好,谢谢。在这种情况下,我如何将共享的 ctype 数组设置为正确的尺寸,我已经很长时间没有使用 C 语言了。
  • 同样,这行得通,但是当我进入下一行时,我得到了TypeError: Cannot cast scalar from dtype('S63') to dtype('uint8') according to the rule 'same_kind',这令人沮丧。我假设 S63 是str,因为这就是导入的文本,即使我将它直接转换为一个 numpy 数组,我也会得到同样的错误。将字符串转换为字符数组似乎异常复杂。目前不知道该怎么做。
  • @Will:答案已扩展。
  • 啊,我想我明白了。所以此时我唯一的问题是,我是否应该将我的原始数据从文件句柄切换到一个数组,然后强制类型为 unicode null 终止字符串,这样我就可以更轻松地将其转换为缓冲区?我觉得如果我的线条更统一且长度相同,那会容易得多,但对于我坚持使用的东西来说,这是不可能的。那么,np.copyto(X_np, np.array(raw, dtype=np.uint8) 可能是最好的方法吗?
  • @Will:你正在重塑。你不应该。 (这就是为什么我的那个版本的示例行没有reshape。)至于U70,我确实说过你需要更大的缓冲区。
猜你喜欢
  • 2021-03-05
  • 2023-01-05
  • 1970-01-01
  • 2017-09-18
  • 2020-04-22
  • 1970-01-01
  • 1970-01-01
  • 2013-04-02
  • 2016-05-22
相关资源
最近更新 更多