c# - CSharp:无法读取 LARGE .npy 文件。例外是“NumSharp.dll 算术运算导致溢出”。
问题描述
我正在尝试在 CSharp 中读取一个大的 .npy 文件。为了做到这一点,我正在尝试使用NumSharp nuget。
该文件是 7GB 锯齿状浮点数组 (float[][])。它有大约 100 万个向量,每个向量都是 960 维。
注意: 更具体地说,我使用的数据是来自以下链接Approximate Nearest Neighbors Large datasets的 GIST 。
以下是我用来加载数据的方法,但它失败并出现异常:
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.OverflowException” NumSharp.dll 中发生“System.OverflowException”类型的未处理异常算术运算导致溢出。
我该如何解决这个问题?
更新
如果文件太大,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);
解决方案
我看到您已经找到了解决方法。万一您现在想知道问题的原因,那是因为Array
.NET 中的类的限制。
该np.load(string path)
方法在此处定义,然后依次调用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
是向量的数量和它们的形状。
接下来,我们来看看readValueMatrix
方法。
int total = 1;
for (int i = 0; i < shape.Length; i++)
total *= shape[i];
var buffer = new byte[bytes * total];
// omitted
NumSharp 试图创建一个byte
大小为 equals 的一维数组bytes * total
。这里,bytes
是 4,total
是向量的数量乘以所有维度的大小。
但是,在 .NET 中,byte
数组的任何给定维度中的最大索引是0X7FFFFFC7
,即2147483591
,如此处所述。我还没有下载你的数据,但我猜它足够大了bytes * total > 2147483591
。
请注意,如果您想使用 NumSharp 将数据写回 npy 文件,那么您将在writeValueMatrix
方法中遇到同样的问题。
推荐阅读
- python - Django 休息框架嵌套序列化程序不适用于 M2M 关系
- javascript - sublime JsFormat - React.js 格式化
- php - 是否有任何精确的程序或技术可以教训调试时间?
- java - Java:标记器在下一个标记之后获取标记
- python - 使用 matplotlib 在我的 x 轴上绘制时间,但是它从 0 开始,而不是实际开始时间
- c# - 使用“如果 API 中已存在此内容”类型语句
- javascript - Rails 将日期对象传递给 javascript
- google-bigquery - 如何查看大查询表的创建表 DDL?
- ruby-on-rails - 创建按两个字段分组的折线图
- python - TwiML 在
标签