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