Python:用相同的键和大小连接许多numpy数组

Python:用相同的键和大小连接许多numpy数组,python,numpy,dictionary,concatenation,Python,Numpy,Dictionary,Concatenation,我有一个在循环中调用的函数,它返回一个dict(dsst_mean),其中包含大约50个变量。所有变量都是长度为10的numpy数组 循环大约迭代3000次。我现在在每个循环的末尾进行连接,这样我就有了一个“dsst_mean_all”的dict,它在每次迭代中都会变大 source = [dsst_mean_all, dsst_mean] for key in source[0]: dsst_mean_all[ke

我有一个在循环中调用的函数,它返回一个dict(dsst_mean),其中包含大约50个变量。所有变量都是长度为10的numpy数组

循环大约迭代3000次。我现在在每个循环的末尾进行连接,这样我就有了一个“dsst_mean_all”的dict,它在每次迭代中都会变大

source = [dsst_mean_all, dsst_mean]                
for key in source[0]:                    
    dsst_mean_all[key] = np.concatenate([d[key] for d in source])
这是可行的,但我知道这不是有效的。我在初始化'dsst_mean_all'dict时也遇到问题。(我目前正在使用dict.fromkeys()来完成此操作。)

我的问题是:有哪些选项可以更有效地做到这一点?我想我可以将dsst_mean dict存储在一个列表中,然后在最后连接一个。但我不确定在内存中保存3000多个numpy数组是否是个好主意。我知道这取决于大小,但不幸的是,现在我没有对每个“dsst_mean”dict的大小进行估计


谢谢。

通常我们建议在列表中收集值,并在最后制作一次数组。这里的新事物是我们需要迭代字典的键来完成这个集合

例如:

用于生成单个词典的函数:

In [804]: def foo(i):
     ...:     return {k:np.arange(5) for k in ['A','B','C']}
     ...: 
In [805]: foo(0)
Out[805]: 
{'A': array([0, 1, 2, 3, 4]),
 'B': array([0, 1, 2, 3, 4]),
 'C': array([0, 1, 2, 3, 4])}
收藏家词典:

In [806]: dd = {k:[] for k in ['A','B','C']}
迭代,收集列表中的数组:

In [807]: for _ in range(3):
     ...:     x = foo(None)
     ...:     for k,v in dd.items():
     ...:         v.append(x[k])
     ...:         
In [808]: dd
Out[808]: 
{'A': [array([0, 1, 2, 3, 4]), array([0, 1, 2, 3, 4]), array([0, 1, 2, 3, 4])],
 'B': [array([0, 1, 2, 3, 4]), array([0, 1, 2, 3, 4]), array([0, 1, 2, 3, 4])],
 'C': [array([0, 1, 2, 3, 4]), array([0, 1, 2, 3, 4]), array([0, 1, 2, 3, 4])]}
字典上的另一次迭代将列表转换为某种数组(
堆栈
串联
,由您选择):

长度为10的3000个数组的列表将比一个30000个数字的数组占用更多的内存,但不会急剧增加


您可以在第一次将所有词典收集到一个列表中,但您仍然需要像这样将它们合并到词典中。

这样不仅效率低下:而且非常不安全:您更改了正在迭代的词典。你的程序可以跳过键,在一个键上迭代两次,甚至陷入无限循环。那么你有什么建设性的建议吗?将它们存储为列表是可以的,直到你知道这是内存问题。它不应该在内存方面增加太多开销,而且比每次迭代都创建numpy数组效率更高。
In [810]: for k,v in dd.items():
     ...:     dd[k]=np.stack(v,axis=0)
     ...:     
In [811]: dd
Out[811]: 
{'A': array([[0, 1, 2, 3, 4],
        [0, 1, 2, 3, 4],
        [0, 1, 2, 3, 4]]), 'B': array([[0, 1, 2, 3, 4],
        [0, 1, 2, 3, 4],
        [0, 1, 2, 3, 4]]), 'C': array([[0, 1, 2, 3, 4],
        [0, 1, 2, 3, 4],
        [0, 1, 2, 3, 4]])}