1365 {
1366 using (var reader = new BinaryReader(File.Open(filePath, FileMode.Open)))
1367 {
1368
1369 byte[] magic = reader.ReadBytes(6);
1370 string magicString = Encoding.ASCII.GetString(magic);
1371 if (magicString != "?NUMPY")
1372 {
1373 throw new InvalidOperationException("Invalid .npy file.");
1374 }
1375
1376
1377 reader.BaseStream.Seek(2, SeekOrigin.Current);
1378
1379
1380 byte[] headerLengthBytes = reader.ReadBytes(2);
1381 int headerLength = BitConverter.ToInt16(headerLengthBytes, 0);
1382
1383
1384 byte[] headerBytes = reader.ReadBytes(headerLength);
1385 string headerString = Encoding.ASCII.GetString(headerBytes).Replace("True", "true").Replace("False", "false").Replace("(", "[").Replace(")", "]");
1386
1387
1388 var settings = new JsonSerializerSettings
1389 {
1390 ContractResolver = new CamelCasePropertyNamesContractResolver()
1391 };
1392
1393
1394 NpyHeader header = JsonConvert.DeserializeObject<NpyHeader>(headerString, settings);
1395 var shape = header.shape;
1396 var dtype = header.descr;
1397 NpyDataType type = GetNpyTypeEnum(dtype);
1398
1399
1400 int totalElements = shape.Aggregate(1, (acc, dim) => acc * dim);
1401
1402
1404 int dataSize = totalElements * elementSize;
1405
1406
1407 byte[] dataBytes = reader.ReadBytes(dataSize);
1408
1409
1410 Array data = null;
1411 switch (type)
1412 {
1413 case NpyDataType.UInt8:
1414 data = new byte[dataBytes.Length];
1415 Buffer.BlockCopy(dataBytes, 0, data, 0, dataBytes.Length);
1416 break;
1417
1418 case NpyDataType.Int8:
1419 data = new sbyte[dataBytes.Length];
1420 Buffer.BlockCopy(dataBytes, 0, data, 0, dataBytes.Length);
1421 break;
1422
1423 case NpyDataType.UInt16:
1424 data = new ushort[totalElements];
1425 for (int i = 0; i < data.Length; i++)
1426 {
1427 data.SetValue(BitConverter.ToUInt16(dataBytes, i * 2), i);
1428 }
1429 break;
1430
1431 case NpyDataType.Int16:
1432 data = new short[totalElements];
1433 for (int i = 0; i < data.Length; i++)
1434 {
1435 data.SetValue(BitConverter.ToInt16(dataBytes, i * 2), i);
1436 }
1437 break;
1438
1439 case NpyDataType.UInt32:
1440 data = new uint[totalElements];
1441 for (int i = 0; i < data.Length; i++)
1442 {
1443 data.SetValue(BitConverter.ToUInt32(dataBytes, i * 4), i);
1444 }
1445 break;
1446
1447 case NpyDataType.Int32:
1448 data = new int[totalElements];
1449 for (int i = 0; i < data.Length; i++)
1450 {
1451 data.SetValue(BitConverter.ToInt32(dataBytes, i * 4), i);
1452 }
1453 break;
1454
1455 case NpyDataType.UInt64:
1456 data = new ulong[totalElements];
1457 for (int i = 0; i < data.Length; i++)
1458 {
1459 data.SetValue(BitConverter.ToUInt64(dataBytes, i * 8), i);
1460 }
1461 break;
1462
1463 case NpyDataType.Int64:
1464 data = new long[totalElements];
1465 for (int i = 0; i < data.Length; i++)
1466 {
1467 data.SetValue(BitConverter.ToInt64(dataBytes, i * 8), i);
1468 }
1469 break;
1470
1471 case NpyDataType.Float16:
1472
1473
1474 break;
1475
1476 case NpyDataType.Float32:
1477 data = new float[totalElements];
1478 for (int i = 0; i < data.Length; i++)
1479 {
1480 data.SetValue(BitConverter.ToSingle(dataBytes, i * 4), i);
1481 }
1482 break;
1483
1484 case NpyDataType.Float64:
1485 data = new double[totalElements];
1486 for (int i = 0; i < data.Length; i++)
1487 {
1488 data.SetValue(BitConverter.ToDouble(dataBytes, i * 8), i);
1489 }
1490 break;
1491
1492 case NpyDataType.Complex64:
1493 data = new (float, float)[totalElements];
1494 for (int i = 0; i < data.Length; i++)
1495 {
1496 var real = BitConverter.ToSingle(dataBytes, i * 8);
1497 var imaginary = BitConverter.ToSingle(dataBytes, i * 8 + 4);
1498 data.SetValue((real, imaginary), i);
1499 }
1500 break;
1501
1502 case NpyDataType.Complex128:
1503 data = new (double, double)[totalElements];
1504 for (int i = 0; i < data.Length; i++)
1505 {
1506 var real = BitConverter.ToDouble(dataBytes, i * 16);
1507 var imaginary = BitConverter.ToDouble(dataBytes, i * 16 + 8);
1508 data.SetValue((real, imaginary), i);
1509 }
1510 break;
1511
1512 default:
1513 throw new ArgumentException("Unsupported NpyDataType", nameof(type));
1514 }
1515
1516 return (shape, type, data);
1517 }
1518 }
static int GetElementSize(NpyDataType type)
Helper function to get the size of the elements based on dtype.
Definition Bio.cs:1525