CSharp:无法读取大型.npy文件。异常是&Quot;NumSharp.dll算术运算导致溢出。&Quot; [英] CSharp: Failed to read LARGE .npy file. Exception is "NumSharp.dll Arithmetic operation resulted in an overflow."

查看:63
本文介绍了CSharp:无法读取大型.npy文件。异常是&Quot;NumSharp.dll算术运算导致溢出。&Quot;的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试读取CSharp中的一个大.npy文件。 为此,我尝试使用NumSharpNuget。

该文件为7 GB交错浮点数组(Float[][])。它有大约100万个向量,每个向量是960维。

注意: 更具体地说,我使用的数据是来自以下链接的GISTApproximate Nearest Neighbors Large datasets

以下是我用来加载数据的方法,但由于出现异常而失败:

    private static void ReadNpyVectorsFromFile(string pathPrefix, out List<float[]> candidates)
    {
        var npyFilename = @$"{pathPrefix}.npy";
        
        var v = np.load(npyFilename);//NDArray
        
        candidates = v
            .astype(np.float32)
            .ToJaggedArray<float>()
            .OfType<float[]>()
            .Select(a =>
            {
                return a.OfType<float>().ToArray();
            })
            .ToList();
    }

例外情况是:

引发异常:NumSharp.dll和 中发生了类型为"System.Overflow Exception"的未经处理的异常 NumSharp.dll算术运算导致溢出。

如何解决此问题?


更新

如果文件太大,NumSharp包有一个限制。 阅读下面的评论/答案以获得更多解释。 我添加了一个带有解决方法建议的答案

但是, 一个很好的替代方法是将数据保存为.npz(请参阅:numpy.savez()),然后使用以下包即可完成此工作:

https://github.com/matajoh/libnpy

代码示例:

        NPZInputStream npz = new NPZInputStream(npyFilename);
        var keys = npz.Keys();
        //var header = npz.Peek(keys[0]);
        var t = npz.ReadFloat32(keys[0]);

        Debug.Assert(t.DataType == DataType.FLOAT32);

推荐答案

我看到您已经找到了解决办法。如果您现在想知道问题的原因,这是因为.NET中Array类的限制。

np.load(string path)方法被定义为here,该方法又调用np.load(Stream stream)

int bytes;
Type type;
int[] shape;
if (!parseReader(reader, out bytes, out type, out shape))
    throw new FormatException();

Array array = Arrays.Create(type, shape.Aggregate((dims, dim) => dims * dim));

var result = new NDArray(readValueMatrix(reader, array, bytes, type, shape));
return result.reshape(shape);
这里,bytes是您的日期类型的大小。由于您使用的是float,因此此值为4。和shape是矢量的数量和形状。

接下来,我们来看看readValueMatrixmethod

int total = 1;
for (int i = 0; i < shape.Length; i++)
    total *= shape[i];
var buffer = new byte[bytes * total];
// omitted
NumSharp正在尝试创建大小等于bytes * total的一维byte数组。这里,bytes是4,total是向量的数量乘以所有维度的大小。

然而,在.NET中,byte数组在任何给定维度上的最大索引是0X7FFFFFC7,即2147483591,如文档here所示。我还没有下载您的数据,但我猜它已经足够大了,bytes * total > 2147483591

请注意,如果要使用NumSharp将数据写回NPY文件,则在writeValueMatrixmethod中也会遇到同样的问题。

这篇关于CSharp:无法读取大型.npy文件。异常是&Quot;NumSharp.dll算术运算导致溢出。&Quot;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆