2

我有大量从 python 编写的 numpy .npz 格式的数据文件。出于几个原因,我想将它们直接读入 C#。
数据文件包含许多不同类型的一维数组——一些是字节数组,还有一些是双精度数组。谁能给我一些关于如何实现这一目标的建议?或者我可能在下面做错了什么?

我曾尝试使用 Accord.NET.NPZFormat 但无法弄清楚如何使其工作。我想可能是因为你必须给它一个返回类型,并且因为数组的类型不同,它会失败。这是一个链接: http ://accord-framework.net/docs/html/M_Accord_IO_NpzFormat_Load__1.htm

我在这里与语法作斗争,不确定使用什么作为“T”。我得到的最接近的是以下内容,但结果中似乎没有任何数据。Accord.IO 没有示例代码。

public static void LoadNPZ(string zip_file, string npz_file)
{
  byte[] ret = new byte[0];
  using (ZipArchive zip = ZipFile.OpenRead(zip_file))
  {
    foreach (ZipArchiveEntry entry in zip.Entries)
    {
      if (entry.Name == npz_file + ".npz")
      {
        Stream fs = entry.Open();
        ret = new byte[fs.Length];
        fs.Read(ret, 0, (int)fs.Length);
      }
    }
  }
  if (ret.Length==0)
  {
    return;
  }

  var ret2 = NpzFormat.Load<object[]>(ret);
};
4

2 回答 2

2

您可以使用NumSharp库。

假设您在 Python 中创建了这些数据。

import numpy as np

arr = np.array([1,2,3,4])
single = arr.astype(np.single)
double = arr.astype(np.double)

np.savez('single.npz', data=single)
np.savez('double.npz', data=double)

阅读它们的 C# 代码如下。

using NumSharp;

var singleContent = np.Load_Npz<float[]>("single.npz"); // type is NpzDictionary
var singleArray = singleContent["data.npy"]; // type is float[]

var doubleContent = np.Load_Npz<double[]>("double.npz"); // type is NpzDictionary
var doubleArray = doubleContent["data.npy"]; // type is double[]

如果您不为数组指定名称,则默认名称为arr_0,C# 代码将是这样的。

var singleArray = singleContent["arr_0.npy"];
var doubleArray = doubleContent["arr_0.npy"];

请注意,NumSharp 具有以下限制。

  • 每个维度的大小必须小于 2,147,483,591 字节。示例:对于整数(4 字节),每个维度必须少于 536,870,898 个元素。
  • 如果您使用的是 .NET Framework,则最大数组大小为 2GB(考虑所有维度)。在 64 位平台上,可以通过启用该gcAllowVeryLargeObjects标志来避免此限制。

更多信息可以在这个答案和这个博客文章中找到(免责声明:我是他们两个的作者)。

于 2021-08-05T13:34:03.983 回答
-2

我经常使用 C# 和 python,我的建议是创建一个 COM 服务器

http://timgolden.me.uk/pywin32-docs/html/com/win32com/HTML/QuickStartServerCom.html

然后在python中你可以简单地拥有类似的东西

import numpy as np

class NPtoCSharp:
    _reg_clsid_ = "{7CC9F362-486D-11D1-BB48-0000E838A65F}"
    _public_methods_ = ['load_file']

    _public_attrs_ = ['arr', 'the_file']

    _reg_desc_ = "Python NPZ Loader"

    _reg_progid_ = "NPtoCSharp"
    def __init__(self):

        self.arr = None
        self.the_file = None
    def load_file(self):

        self.arr = np.load(self.the_file)

        return self.arr

然后在 C#

public void init_python()
{
    Type NPtoCSharp = Type.GetTypeFromProgID("NPtoCSharp");
    NPtoCSharpInst = Activator.CreateInstance(NPtoCSharp);
    NPtoCSharpInst.the_file = 'myfile.npz';
}

不完整,但我希望你能明白。

于 2019-04-25T16:14:40.823 回答