Python在大文件写入时静默挂起

Python在大文件写入时静默挂起,python,file,serialization,yaml,pickle,Python,File,Serialization,Yaml,Pickle,我正在尝试将大量的numpy nd_阵列写入磁盘 该列表大约有50000个元素长 每个元素都是一个整数大小(~2048,2)的nd_数组。阵列具有不同的形状 我现在使用的方法是 我也试过泡菜,它也有同样的问题: 在一些小的列表中(大约3400长),这很好,完成得足够快(我不能说这是答案,但可能是它 当我在开发需要快速循环的应用程序时,我发现代码中的某些东西非常慢。它正在打开/关闭yaml文件 通过使用JSON解决了这个问题 不要将YAML用于任何其他用途,除非它是一种您不经常打开的配置 阵列保存

我正在尝试将大量的numpy nd_阵列写入磁盘

该列表大约有50000个元素长

每个元素都是一个整数大小(~2048,2)的nd_数组。阵列具有不同的形状

我现在使用的方法是

我也试过泡菜,它也有同样的问题:


在一些小的列表中(大约3400长),这很好,完成得足够快(我不能说这是答案,但可能是它

当我在开发需要快速循环的应用程序时,我发现代码中的某些东西非常慢。它正在打开/关闭yaml文件

通过使用JSON解决了这个问题

不要将YAML用于任何其他用途,除非它是一种您不经常打开的配置

阵列保存的解决方案:

np.save(path,array) # path = path+name+'.npy'
如果您确实需要保存数组列表,我建议您使用数组路径保存列表(您将使用np.save保存在磁盘上的数组本身)。在磁盘上保存python对象并不是您真正想要的。您想要的是使用np.save保存numpy数组

完整解决方案(保存示例):

完整解决方案(加载示例):

进一步忠告:

Python无法真正处理大型数组。此外,如果您已经在列表中加载了多个数组,那么从速度和内存的角度来看,总是一次使用一个或两个数组。其余的数组必须在磁盘上等待。因此,与其使用对象引用,不如使用引用作为路径,并在需要时从磁盘加载它

另外,您说过您不想手动组合列表

可能的解决方案,我不建议,但可能正是您想要的

>>> a = np.zeros(shape = [10,5,3])
>>> b = np.zeros(shape = [7,7,9])
>>> c = [a,b]
>>> np.save('data.npy',c)
>>> d = np.load('data.npy')
>>> d.shape
(2,)
>>> type(d)
<type 'numpy.ndarray'>
>>> d.shape
(2,)
>>> d[0].shape
(10, 5, 3)
>>> 
>a=np.zero(形状=[10,5,3])
>>>b=np.零(形状=[7,7,9])
>>>c=[a,b]
>>>np.save('data.npy',c)
>>>d=np.load('data.npy')
>>>d.形状
(2,)
>>>类型(d)
>>>d.形状
(2,)
>>>d[0]。形状
(10, 5, 3)
>>> 

我相信我不需要对上面提到的代码进行注释。但是,加载后,您将丢失列表,因为列表将转换为numpy数组。

我不能说这是答案,但可能是答案

当我在开发需要快速循环的应用程序时,我发现代码中的某些东西非常慢。它正在打开/关闭yaml文件

通过使用JSON解决了这个问题

不要将YAML用于任何其他用途,除非它是一种您不经常打开的配置

阵列保存的解决方案:

np.save(path,array) # path = path+name+'.npy'
如果您确实需要保存数组列表,我建议您使用数组路径保存列表(您将使用np.save保存在磁盘上的数组本身)。在磁盘上保存python对象并不是您真正想要的。您想要的是使用np.save保存numpy数组

完整解决方案(保存示例):

完整解决方案(加载示例):

进一步忠告:

Python无法真正处理大型数组。此外,如果您已经在列表中加载了多个数组,那么从速度和内存的角度来看,总是一次使用一个或两个数组。其余的数组必须在磁盘上等待。因此,与其使用对象引用,不如使用引用作为路径,并在需要时从磁盘加载它

另外,您说过您不想手动组合列表

可能的解决方案,我不建议,但可能正是您想要的

>>> a = np.zeros(shape = [10,5,3])
>>> b = np.zeros(shape = [7,7,9])
>>> c = [a,b]
>>> np.save('data.npy',c)
>>> d = np.load('data.npy')
>>> d.shape
(2,)
>>> type(d)
<type 'numpy.ndarray'>
>>> d.shape
(2,)
>>> d[0].shape
(10, 5, 3)
>>> 
>a=np.zero(形状=[10,5,3])
>>>b=np.零(形状=[7,7,9])
>>>c=[a,b]
>>>np.save('data.npy',c)
>>>d=np.load('data.npy')
>>>d.形状
(2,)
>>>类型(d)
>>>d.形状
(2,)
>>>d[0]。形状
(10, 5, 3)
>>> 
我相信我不需要对上面提到的代码进行注释。但是,加载后,您将丢失列表,因为列表将转换为numpy数组。

对于代码

import numpy as np
import yaml

x = []
for i in range(0,50000):
    x.append(np.random.rand(2048,2))
print("Arrays generated")
with open("t.yaml", 'w+', encoding='utf8') as outfile:
    yaml.dump(x, outfile, default_flow_style=False, allow_unicode=True)
在我使用Python 3.7和PyYAML 3.13的系统(MacOSX、i7、16 GiB RAM、SSD)上,完成时间为61分钟。在保存过程中,Python占用了大约5 GB的内存,最终文件大小为2 GB。这也显示了文件格式的开销:数据大小为50k*2048*2*8(在python中,浮点的大小通常为64位)=1562 MB,这意味着yaml的性能差约1.3倍(序列化/反序列化也需要时间)

回答您的问题:

  • 没有正确或不正确的方法。要进行进度更新和 估计完成时间并不容易(例如:其他任务可能会 干扰估计,可能会使用内存等资源 您可以依赖支持该功能的库或实现 你自己做的事情(正如另一个答案所暗示的)
  • 不确定“调试”是否是正确的术语,因为在实践中可能是进程太慢了。进行性能分析并不容易,尤其是在 使用多个/不同的库。我首先要说的是清楚的 要求:您希望从保存的文件中得到什么?他们需要吗 是yaml吗?将50k阵列保存为yaml似乎不是最佳解决方案 如果你关心性能,你应该先问自己“哪种格式最适合我想要的?”(但你没有给出细节,所以不能说…)
  • 编辑:如果您想要快速的东西,请使用pickle。代码:

    import numpy as np
    import yaml
    import pickle
    
    x = []
    for i in range(0,50000):
        x.append(np.random.rand(2048,2))
    print("Arrays generated")
    pickle.dump( x, open( "t.yaml", "wb" ) )
    
    在9秒内完成,并生成一个1.5GBytes的文件(无开销)。当然,pickle格式应该在与yaml完全不同的情况下使用…

    用于代码

    import numpy as np
    import yaml
    
    x = []
    for i in range(0,50000):
        x.append(np.random.rand(2048,2))
    print("Arrays generated")
    with open("t.yaml", 'w+', encoding='utf8') as outfile:
        yaml.dump(x, outfile, default_flow_style=False, allow_unicode=True)
    
    在我使用Python 3.7和PyYAML 3.13的系统(MacOSX、i7、16 GiB RAM、SSD)上,完成时间为61分钟。在保存过程中,Python占用了大约5 GB的内存,最终文件大小为2 GB。这也显示了文件格式的开销:数据大小为50k*2048*2*8(在python中,浮点的大小通常为64位)=1562 MB,这意味着yaml的性能差约1.3倍(序列化/反序列化也需要时间)

    回答您的问题:

  • 没有正确或不正确的方法。要进行进度更新和 估计完成时间并不容易(例如:其他任务可能会 干扰估计,可能会使用内存等资源 向上的