0

numpy结构化数组是 Python 的替代品吗dict

我想节省内存,但我无法承受性能下降太多。

就我而言,键是str,值是int

如果它们实际上是替代品,你能给出一个快速的转换线吗?

我也不介意您是否可以提出不同的选择。

我需要节省内存,因为某些字典的内存大于 50Gb,我需要一次打开多个字典,并且“只有”192 GB RAM 可用。

4

3 回答 3

1

numpy 数组使用连续的内存块,并且只能存储一种类型的对象,如 int、float、string 或其他对象。每个项目在内存中分配固定字节。

Numpy 还提供了一组函数用于操作,如遍历数组、算术运算、对使用 c 实现的那些存储项的一些字符串操作。由于这些操作没有 python 的开销,因此它们在内存和处理能力方面通常更有效

当您需要键值对时,您也可以将其存储在类似于 c-struct 的 numpy 数组中,但它不会具有 dict 之类的功能,例如查找项目、检查键是否存在过滤等。您必须使用数组功能自己做这些

对您来说更好的选择可能是 pandas 系列,它还使用 numpy 数组来存储其数据,以便在其之上为您提供许多功能

于 2019-09-24T10:14:55.977 回答
1

也许有点晚了,但如果其他人有同样的问题,我做了一个简单的基准测试:

In [1]: import random

In [2]: import string

In [3]: import pandas as pd

In [4]: import sys

In [5]: size = 10**6

In [6]: d = {''.join(random.choices(string.ascii_letters + string.digits, k=32)): random.randrange(size) for _ in range(size)}

In [7]: s = pd.Series(d)

In [8]: a = s.values.view(list(zip(s.index, ['i8'] * size)))

In [9]: key = s.index[random.randrange(size)]

In [10]: %timeit d[key]
61.5 ns ± 1.46 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

In [11]: %timeit s[key]
3.54 µs ± 158 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

In [12]: %timeit a[key]
154 ns ± 1.63 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

In [13]: sys.getsizeof(d)
Out[13]: 41943136

In [14]: sys.getsizeof(s)
Out[14]: 130816632

似乎np.ndarraydict(这是可以接受的)慢了大约 2-3 倍,而性能pd.Series比其他两个差得多。至于空间效率,dict也跑赢大盘pd.Series。我没有找到一种方法来获取 numpy 结构化数组的内存使用情况(尝试使用sys.getsizeofand ndarray.nbytes,但似乎两者都缺少字段的大小)。

于 2021-05-10T08:54:39.800 回答
0

您可以使用对象的内存大小sys

import sys
import numpy as np

x = np.array([('Rex', 9, 81.0), ('Fido', 3, 27.0)],
    dtype=[('name', 'U10'), ('age', 'i4'), ('weight', 'f4')])

print(sys.getsizeof(x))

y = {
    1 : {
        'name': 'Rex',
        'age' : 9,
        'weight' : 81.0
    },
    2 : {
        'name': 'Fido',
        'age' : 3,
        'weight' : 27.0
    }
}

print(sys.getsizeof(y))
  1. 192
  2. 240

这些是结果。我相信 numpy 结构化数组的内存效率相对较高。

于 2019-09-24T10:01:46.043 回答