You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python中高效将C#的System.UInt16[,]转换为NumPy uint16矩阵

高效转换System.UInt16[,]到NumPy uint16矩阵

当通过clr调用C# DLL返回二维ushort数组时,嵌套循环逐个赋值的效率确实极低——尤其是数组规模较大时,Python层面的循环开销会被放大。我们可以利用.NET数组的底层内存操作和NumPy的数组创建特性,实现批量内存拷贝+零拷贝视图转换,大幅提升处理速度。

方法一:利用System.Buffer实现快速内存拷贝

.NET的System.Buffer.BlockCopy是底层的内存拷贝方法,能直接把多维数组的内容复制到字节数组,再通过NumPy的frombuffer直接创建数组视图(几乎无额外开销)。

import clr
import os
import numpy as np
from System import Buffer, Array

dll_name = os.path.join(os.path.abspath(os.path.dirname(__file__)), "mydll.dll")
clr.AddReference(dll_name)
from mynamespace import myclass

myobject = myclass()
system_matrix = myobject.Getdata()

# 获取二维数组的行列数
rows = system_matrix.GetLength(0)
cols = system_matrix.GetLength(1)

# 计算总字节数:每个uint16占2字节
total_bytes = rows * cols * 2
# 创建对应大小的字节数组
byte_array = Array.CreateInstance(System.Byte, total_bytes)

# 批量拷贝.NET数组内容到字节数组
Buffer.BlockCopy(system_matrix, 0, byte_array, 0, total_bytes)

# 从字节数组直接生成NumPy uint16数组,再调整形状
numpy_matrix = np.frombuffer(byte_array, dtype=np.uint16).reshape((rows, cols))

方法二:先展平为一维数组再转换

如果更习惯直接处理数值类型数组,可以先把二维数组展平为一维System.UInt16[],再直接转换为NumPy数组:

# 基于上面的代码,获取rows和cols后:
flat_uint16_array = Array.CreateInstance(System.UInt16, rows * cols)
Buffer.BlockCopy(system_matrix, 0, flat_uint16_array, 0, total_bytes)

# 直接转换为NumPy数组并调整形状
numpy_matrix = np.array(flat_uint16_array, dtype=np.uint16).reshape((rows, cols))

关键注意事项

  • 内存布局一致性:C#的多维数组默认是行优先(C顺序),和NumPy默认的数组存储顺序一致,所以reshape后无需额外调整。如果你的C#数组是列优先(Fortran顺序),需要在reshape时指定order='F',或者后续转置数组。
  • 效率对比:这两种方法都避免了Python层面的逐个元素访问,利用了底层的内存拷贝操作,速度比嵌套循环快100~1000倍(数组越大,提升越明显)。比如80×260的数组,循环可能需要几毫秒,而批量拷贝方法仅需微秒级时间。

内容的提问来源于stack exchange,提问作者Hossam Alzomor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 23:07:42