rsnumpy 1.0.1__tar.gz → 1.0.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. {rsnumpy-1.0.1 → rsnumpy-1.0.2}/.gitignore +3 -1
  2. {rsnumpy-1.0.1 → rsnumpy-1.0.2}/Cargo.lock +35 -1
  3. rsnumpy-1.0.2/Cargo.toml +36 -0
  4. {rsnumpy-1.0.1 → rsnumpy-1.0.2}/PKG-INFO +1 -2
  5. {rsnumpy-1.0.1 → rsnumpy-1.0.2}/README.md +0 -1
  6. rsnumpy-1.0.2/RELEASE_NOTES.md +82 -0
  7. {rsnumpy-1.0.1 → rsnumpy-1.0.2}/build_wheel.sh +16 -6
  8. {rsnumpy-1.0.1 → rsnumpy-1.0.2}/pyproject.toml +1 -1
  9. {rsnumpy-1.0.1 → rsnumpy-1.0.2}/python/rsnumpy/__init__.py +13 -29
  10. rsnumpy-1.0.2/python/rsnumpy/array_methods.py +225 -0
  11. {rsnumpy-1.0.1 → rsnumpy-1.0.2}/python/rsnumpy/array_ops.py +21 -165
  12. {rsnumpy-1.0.1 → rsnumpy-1.0.2}/python/rsnumpy/matlib.py +11 -27
  13. {rsnumpy-1.0.1 → rsnumpy-1.0.2}/python/rsnumpy/random/__init__.py +4 -0
  14. {rsnumpy-1.0.1 → rsnumpy-1.0.2}/python/rsnumpy/statistics.py +10 -19
  15. rsnumpy-1.0.2/src/fft.rs +162 -0
  16. {rsnumpy-1.0.1 → rsnumpy-1.0.2}/src/indexing.rs +126 -185
  17. {rsnumpy-1.0.1 → rsnumpy-1.0.2}/src/lib.rs +805 -232
  18. {rsnumpy-1.0.1 → rsnumpy-1.0.2}/src/linalg.rs +318 -330
  19. {rsnumpy-1.0.1 → rsnumpy-1.0.2}/src/random.rs +213 -142
  20. rsnumpy-1.0.1/.trae/rules/git-commit-message.md +0 -6
  21. rsnumpy-1.0.1/Cargo.toml +0 -19
  22. rsnumpy-1.0.1/python/rsnumpy/array_methods.py +0 -474
  23. rsnumpy-1.0.1/src/fft.rs +0 -256
  24. {rsnumpy-1.0.1 → rsnumpy-1.0.2}/.github/ci.yml +0 -0
  25. {rsnumpy-1.0.1 → rsnumpy-1.0.2}/.github/release.yml +0 -0
  26. {rsnumpy-1.0.1 → rsnumpy-1.0.2}/.github/workflows/rust-clippy.yml +0 -0
  27. {rsnumpy-1.0.1 → rsnumpy-1.0.2}/LICENSE +0 -0
  28. {rsnumpy-1.0.1 → rsnumpy-1.0.2}/plots.py +0 -0
  29. {rsnumpy-1.0.1 → rsnumpy-1.0.2}/python/rsnumpy/char.py +0 -0
  30. {rsnumpy-1.0.1 → rsnumpy-1.0.2}/python/rsnumpy/io.py +0 -0
  31. {rsnumpy-1.0.1 → rsnumpy-1.0.2}/python/rsnumpy/linalg/__init__.py +0 -0
  32. {rsnumpy-1.0.1 → rsnumpy-1.0.2}/python/rsnumpy/math_functions.py +0 -0
  33. {rsnumpy-1.0.1 → rsnumpy-1.0.2}/python/rsnumpy/polynomial/__init__.py +0 -0
@@ -21,7 +21,6 @@ uv.lock
21
21
  # IDE
22
22
  .vscode/
23
23
  .idea/
24
- .trae/
25
24
  *.swp
26
25
  *.swo
27
26
  *~
@@ -46,3 +45,6 @@ check*.py
46
45
  .venv
47
46
  .env
48
47
  .env.local
48
+ .trae/
49
+ .trae/rules/git-commit-message.md
50
+ git-commit-message.md
@@ -62,6 +62,15 @@ dependencies = [
62
62
  "libbz2-rs-sys",
63
63
  ]
64
64
 
65
+ [[package]]
66
+ name = "cblas-sys"
67
+ version = "0.1.4"
68
+ source = "registry+https://github.com/rust-lang/crates.io-index"
69
+ checksum = "b6feecd82cce51b0204cf063f0041d69f24ce83f680d87514b004248e7b0fa65"
70
+ dependencies = [
71
+ "libc",
72
+ ]
73
+
65
74
  [[package]]
66
75
  name = "cc"
67
76
  version = "1.2.64"
@@ -461,6 +470,8 @@ version = "0.17.2"
461
470
  source = "registry+https://github.com/rust-lang/crates.io-index"
462
471
  checksum = "520080814a7a6b4a6e9070823bb24b4531daac8c4627e08ba5de8c5ef2f2752d"
463
472
  dependencies = [
473
+ "cblas-sys",
474
+ "libc",
464
475
  "matrixmultiply",
465
476
  "num-complex",
466
477
  "num-integer",
@@ -469,6 +480,7 @@ dependencies = [
469
480
  "portable-atomic-util",
470
481
  "rawpointer",
471
482
  "rayon",
483
+ "serde",
472
484
  ]
473
485
 
474
486
  [[package]]
@@ -721,15 +733,17 @@ dependencies = [
721
733
 
722
734
  [[package]]
723
735
  name = "rsnumpy"
724
- version = "1.0.1"
736
+ version = "1.0.2"
725
737
  dependencies = [
726
738
  "ndarray",
739
+ "num-complex",
727
740
  "num-traits",
728
741
  "pyo3",
729
742
  "rand",
730
743
  "rand_distr",
731
744
  "rayon",
732
745
  "rustfft",
746
+ "thiserror",
733
747
  "zip",
734
748
  ]
735
749
 
@@ -864,6 +878,26 @@ version = "0.13.5"
864
878
  source = "registry+https://github.com/rust-lang/crates.io-index"
865
879
  checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca"
866
880
 
881
+ [[package]]
882
+ name = "thiserror"
883
+ version = "2.0.18"
884
+ source = "registry+https://github.com/rust-lang/crates.io-index"
885
+ checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4"
886
+ dependencies = [
887
+ "thiserror-impl",
888
+ ]
889
+
890
+ [[package]]
891
+ name = "thiserror-impl"
892
+ version = "2.0.18"
893
+ source = "registry+https://github.com/rust-lang/crates.io-index"
894
+ checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5"
895
+ dependencies = [
896
+ "proc-macro2",
897
+ "quote",
898
+ "syn",
899
+ ]
900
+
867
901
  [[package]]
868
902
  name = "time"
869
903
  version = "0.3.49"
@@ -0,0 +1,36 @@
1
+ [package]
2
+ name = "rsnumpy"
3
+ version = "1.0.2"
4
+ edition = "2024"
5
+ readme = "README.md"
6
+
7
+ [lib]
8
+ name = "rsnumpy"
9
+ crate-type = ["cdylib"]
10
+
11
+ [dependencies]
12
+ pyo3 = { version = "0.29.0", features = ["extension-module", "abi3-py38"] }
13
+ ndarray = { version = "0.17.2", features = ["rayon", "blas", "serde"] }
14
+ rayon = "1.12.0"
15
+ rand = "0.10.1"
16
+ rand_distr = "0.6.0"
17
+ num-traits = "0.2.19"
18
+ rustfft = "6.4.1"
19
+ zip = "8.6.0"
20
+ num-complex = "0.4.6"
21
+ thiserror = "2.0.0"
22
+
23
+ [features]
24
+ default = []
25
+ blas = ["ndarray/blas"]
26
+
27
+ [profile.release]
28
+ opt-level = 3
29
+ lto = "fat"
30
+ codegen-units = 1
31
+ panic = "abort"
32
+ strip = true
33
+
34
+ [profile.bench]
35
+ opt-level = 3
36
+ debug = false
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rsnumpy
3
- Version: 1.0.1
3
+ Version: 1.0.2
4
4
  Classifier: License :: OSI Approved :: MIT License
5
5
  Classifier: Programming Language :: Rust
6
6
  Classifier: Programming Language :: Python :: Implementation :: CPython
@@ -15,7 +15,6 @@ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
15
15
 
16
16
  **A Rust-powered NumPy-compatible array library.**
17
17
 
18
- ![Build Status](https://github.com/your-username/rsnumpy/actions/workflows/ci.yml/badge.svg)
19
18
  ![License](https://img.shields.io/badge/license-MIT-blue.svg)
20
19
  ![Python Version](https://img.shields.io/badge/python-%3E%3D%203.10-blue.svg)
21
20
  ![Rust Version](https://img.shields.io/badge/rust-%3E%3D%201.75-orange.svg)
@@ -2,7 +2,6 @@
2
2
 
3
3
  **A Rust-powered NumPy-compatible array library.**
4
4
 
5
- ![Build Status](https://github.com/your-username/rsnumpy/actions/workflows/ci.yml/badge.svg)
6
5
  ![License](https://img.shields.io/badge/license-MIT-blue.svg)
7
6
  ![Python Version](https://img.shields.io/badge/python-%3E%3D%203.10-blue.svg)
8
7
  ![Rust Version](https://img.shields.io/badge/rust-%3E%3D%201.75-orange.svg)
@@ -0,0 +1,82 @@
1
+ # Release Notes
2
+
3
+ ## v1.0.2 (2026-06-24)
4
+
5
+ ### 性能优化
6
+
7
+ - **索引模块优化**:向量预分配,提升花式索引性能
8
+ - **数组拼接优化**:`concatenate`、`stack` 等函数性能提升
9
+ - **数组格式化输出优化**:预分配字符串缓冲区、简化切片遍历逻辑
10
+ - **工具函数优化**:`arange`、`reshape` 等函数的预分配和边界处理
11
+ - **IO 函数优化**:`loadtxt`、`savez` 等函数的预分配和遍历逻辑
12
+
13
+ ### 模块重构
14
+
15
+ - **随机数模块重构**:使用 const 初始化线程局部 RNG、优化形状解析预分配、使用 `div_ceil` 计算分块大小、简化采样类型转换
16
+ - **线性代数模块重构**:将 Python 绑定函数移至 PyO3 detach 闭包,避免 GIL 持有过长时间
17
+ - **统计函数优化**:简化 `polyfit`、`cov` 等计算的循环逻辑
18
+
19
+ ### Bug 修复
20
+
21
+ - 修复 `median`、`percentile` 等统计函数的偶数长度判断逻辑
22
+ - 修复部分边界检查的冗余代码
23
+
24
+ ### 构建优化
25
+
26
+ - 新增 `build_wheel.sh` 自动同步版本号的逻辑
27
+ - 优化构建配置,二进制大小略有优化
28
+
29
+ ---
30
+
31
+ ## v1.0.1 (2026-06-24)
32
+
33
+ ### 功能增强
34
+
35
+ - **新增 ArrayFlags 支持**:提供数组标志位查询功能
36
+ - **新增 like-series 数组创建函数**:支持根据已有数组的属性创建新数组
37
+ - **改进 logspace 函数**:优化对数空间生成算法
38
+
39
+ ### 性能提升
40
+
41
+ - **并行加速矩阵运算**:利用多线程并行化矩阵运算
42
+ - **随机数生成优化**:并行加速随机数生成
43
+ - **构建配置优化**:调整编译参数,提升构建效率
44
+
45
+ ### 代码重构
46
+
47
+ - **迁移矩阵和数组操作到 Rust 后端**:将大量矩阵和数组操作从 Python 层迁移到 Rust 层实现
48
+ - **重构 matlib.py 的矩阵函数实现**:优化矩阵函数的代码结构
49
+
50
+ ### 文档更新
51
+
52
+ - 更新 README 中 Python 版本支持要求至 3.10+
53
+ - 更新 README 文档细节并修复格式问题
54
+
55
+ ---
56
+
57
+ ## v1.0.0 (Initial Release)
58
+
59
+ ### 核心功能
60
+
61
+ - **高性能多维数组**:基于 Rust 的 ndarray 实现,提供 NumPy 兼容的 API
62
+ - **数学函数**:支持 sin、cos、exp、sqrt、log 等常见数学函数
63
+ - **数组操作**:支持 reshape、transpose、切片、拼接等操作
64
+ - **统计函数**:支持 sum、mean、std、var、max、min、argmin、argmax 等
65
+ - **线性代数**:支持 det、inv、norm、solve、svd、qr 等矩阵运算
66
+ - **FFT**:支持快速傅里叶变换及其逆变换
67
+ - **随机数**:支持 uniform、normal、integers 等分布,兼容新旧两种 API
68
+ - **多项式**:支持多项式求值、求根、运算和拟合
69
+ - **文件 I/O**:支持 .npy、.npz 和文本文件的读写
70
+
71
+ ### 优势
72
+
73
+ - **性能**:核心计算使用 Rust 实现,部分操作(sum、mean、dot 等)比 NumPy 快 1.2x-2.0x
74
+ - **类型安全**:利用 Rust 的强类型系统避免运行时错误
75
+ - **内存安全**:无数据竞争,无内存泄漏
76
+ - **完整 API**:覆盖 NumPy 常用功能
77
+
78
+ ### 支持平台
79
+
80
+ - Python ≥ 3.10
81
+ - Rust ≥ 1.75
82
+ - macOS、Linux、Windows
@@ -4,17 +4,27 @@ set -euo pipefail
4
4
  # Build Rust lib into Python wheel using maturin
5
5
  # Usage: scripts/build_wheel.sh [--release|--debug] [--out-dir DIR] [--python PYTHON_EXEC]
6
6
 
7
+ # ========== 从 Cargo.toml 读取元信息 ==========
8
+ NAME=$(grep -m1 '^name = ' Cargo.toml | sed 's/name = "\(.*\)"/\1/')
9
+ VERSION=$(grep -m1 '^version = ' Cargo.toml | sed 's/version = "\(.*\)"/\1/')
10
+
11
+ echo "Project: $NAME, Version: $VERSION"
12
+
13
+ # ========== 同步版本到 pyproject.toml ==========
14
+ sed -i '' "s/^version = \".*\"/version = \"$VERSION\"/" pyproject.toml
15
+ echo " -> pyproject.toml version updated to $VERSION"
16
+
17
+ # ========== 同步版本到 python/rsnumpy/__init__.py ==========
18
+ sed -i '' "s/^__version__ = \".*\"/__version__ = \"$VERSION\"/" python/rsnumpy/__init__.py
19
+ echo " -> python/rsnumpy/__init__.py __version__ updated to $VERSION"
20
+
7
21
  RELEASE=true
8
22
  OUT_DIR="wheelhouse"
9
- cache_file="/Users/user/Desktop/rust_project/rsplotlib/python/rsplotlib/rsplotlib.cpython-313-darwin.so"
23
+
10
24
  # 如果 wheelhouse 目录存在, 则删除
11
25
  if [[ -d "$OUT_DIR" ]]; then
12
26
  rm -rf "$OUT_DIR"
13
27
  fi
14
- # 如果 cache_file 目录存在, 则删除
15
- if [[ -f "$cache_file" ]]; then
16
- rm "$cache_file"
17
- fi
18
28
 
19
29
  # Default python executable; may be overridden by --python or positional arg
20
30
  PYTHON_EXEC="python"
@@ -80,4 +90,4 @@ else
80
90
  echo "Warning: no .whl file found in $OUT_DIR; skip install." >&2
81
91
  fi
82
92
 
83
- echo "Done."
93
+ echo "Done."
@@ -4,7 +4,7 @@ build-backend = "maturin"
4
4
 
5
5
  [project]
6
6
  name = "rsnumpy"
7
- version = "1.0.1"
7
+ version = "1.0.2"
8
8
  requires-python = ">=3.10"
9
9
  description = "A Rust-powered NumPy-compatible array library."
10
10
  readme = "README.md"
@@ -29,7 +29,7 @@ from .random import random_module as _random_module
29
29
  from . import char as _char_module
30
30
  from . import matlib as _matlib_module
31
31
 
32
- __version__ = "1.0.1"
32
+ __version__ = "1.0.2"
33
33
 
34
34
  class ArrayFlags:
35
35
  """数组内存布局信息,与 NumPy 的 np.ndarray.flags 兼容。"""
@@ -1338,11 +1338,7 @@ def repmat(a, m, n):
1338
1338
  a = _to_ndarray(a)
1339
1339
  if a.ndim == 1:
1340
1340
  a = a.reshape(1, a.size)
1341
- result = []
1342
- for _ in range(m):
1343
- for row in range(a.shape[0]):
1344
- result.append(a[row].tolist() * n)
1345
- return asarray(result)
1341
+ return tile(a, (m, n))
1346
1342
 
1347
1343
 
1348
1344
  def _to_ndarray(obj):
@@ -1468,28 +1464,28 @@ def zeros_like(a, dtype=None, order='K', subok=True, shape=None):
1468
1464
  """返回与输入形状相同的零数组。"""
1469
1465
  arr = ndarray(a)
1470
1466
  _dtype = dtype if dtype is not None else getattr(arr, '_dtype', 'float64')
1471
- return zeros(arr.shape, dtype=_dtype)
1467
+ return ndarray(_core.zeros_like(arr._array), _dtype=_dtype)
1472
1468
 
1473
1469
 
1474
1470
  def ones_like(a, dtype=None, order='K', subok=True, shape=None):
1475
1471
  """返回与输入形状相同的1数组。"""
1476
1472
  arr = ndarray(a)
1477
1473
  _dtype = dtype if dtype is not None else getattr(arr, '_dtype', 'float64')
1478
- return ones(arr.shape, dtype=_dtype)
1474
+ return ndarray(_core.ones_like(arr._array), _dtype=_dtype)
1479
1475
 
1480
1476
 
1481
1477
  def empty_like(a, dtype=None, order='K', subok=True, shape=None):
1482
1478
  """返回与输入形状相同的空数组。"""
1483
1479
  arr = ndarray(a)
1484
1480
  _dtype = dtype if dtype is not None else getattr(arr, '_dtype', 'float64')
1485
- return empty(arr.shape, dtype=_dtype)
1481
+ return ndarray(_core.empty_like(arr._array), _dtype=_dtype)
1486
1482
 
1487
1483
 
1488
1484
  def full_like(a, fill_value, dtype=None, order='K', subok=True, shape=None):
1489
1485
  """返回与输入形状相同的填充数组。"""
1490
1486
  arr = ndarray(a)
1491
1487
  _dtype = dtype if dtype is not None else getattr(arr, '_dtype', 'float64')
1492
- return full(arr.shape, fill_value, dtype=_dtype)
1488
+ return ndarray(_core.full_like(arr._array, float(fill_value)), _dtype=_dtype)
1493
1489
 
1494
1490
 
1495
1491
  def eye(N, M=None, k=0, dtype=None, order='C'):
@@ -1517,32 +1513,25 @@ def linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None, axis
1517
1513
  start_val = _scalar(_ensure(start))
1518
1514
  stop_val = _scalar(_ensure(stop))
1519
1515
  _dtype = _resolve_dtype(dtype)
1520
- if num == 1:
1521
- result = ndarray([start_val], _dtype=_dtype)
1522
- step = 0.0
1523
- else:
1524
- result = ndarray(_core.linspace(start_val, stop_val, num, endpoint=endpoint))
1525
- if _dtype != "float64":
1526
- result._dtype = _dtype
1527
- step = (stop_val - start_val) / (num - 1) if endpoint else (stop_val - start_val) / num
1516
+ result = ndarray(_core.linspace(start_val, stop_val, num, endpoint=endpoint), _dtype=_dtype)
1528
1517
  if retstep:
1518
+ step = (stop_val - start_val) / (num - 1) if endpoint else (stop_val - start_val) / num
1529
1519
  return result, _float64(step)
1530
1520
  return result
1531
1521
 
1532
1522
 
1533
1523
  def logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None, axis=0):
1534
1524
  """返回对数刻度上均匀间隔的数字。"""
1535
- return power(ndarray([float(base)]), linspace(start, stop, num, endpoint))
1525
+ _dtype = _resolve_dtype(dtype) if dtype else "float64"
1526
+ return ndarray(_core.logspace(float(start), float(stop), num, float(base)), _dtype=_dtype)
1536
1527
 
1537
1528
 
1538
1529
  def geomspace(start, stop, num=50, endpoint=True, dtype=None, axis=0):
1539
1530
  """返回几何级数上均匀间隔的数字。"""
1540
- import math
1541
1531
  if start <= 0 or stop <= 0:
1542
1532
  raise ValueError("geomspace requires positive start and stop values")
1543
- log_start = math.log(start)
1544
- log_stop = math.log(stop)
1545
- return exp(linspace(log_start, log_stop, num, endpoint))
1533
+ _dtype = _resolve_dtype(dtype) if dtype else "float64"
1534
+ return ndarray(_core.geomspace(float(start), float(stop), num), _dtype=_dtype)
1546
1535
 
1547
1536
 
1548
1537
  # ========== 索引函数 ==========
@@ -1943,12 +1932,7 @@ def isnan(x):
1943
1932
 
1944
1933
  def binary_repr(num, width=None):
1945
1934
  """返回整数的二进制表示字符串。"""
1946
- if width is None:
1947
- width = num.bit_length() or 1
1948
- if num >= 0:
1949
- return format(num, 'b').zfill(width)
1950
- # 负数:补码表示
1951
- return format((1 << width) + num, 'b').zfill(width)
1935
+ return _core.binary_repr(num, width)
1952
1936
 
1953
1937
 
1954
1938
  def isinf(x):
@@ -0,0 +1,225 @@
1
+ """
2
+ ndarray 对象方法模块
3
+
4
+ 此模块包含 rsnumpy.ndarray 类的所有对象方法和属性。
5
+ """
6
+
7
+ import rsnumpy._core as _core
8
+ from .__init__ import ndarray, _ensure
9
+
10
+
11
+ def _wrap_result(result, dtype="float64"):
12
+ """包装结果为 ndarray 对象"""
13
+ if hasattr(result, '__class__') and result.__class__.__name__ == 'ndarray':
14
+ return ndarray._wrap(result, _dtype=dtype)
15
+ return result
16
+
17
+
18
+ class NdArrayMethods:
19
+ """ndarray 对象方法集合"""
20
+
21
+ @staticmethod
22
+ def astype(arr, dtype):
23
+ """将数组转换为指定的数据类型。"""
24
+ return _wrap_result(arr._array.astype(dtype))
25
+
26
+ @staticmethod
27
+ def reshape(arr, *shape):
28
+ """改变数组形状而不改变数据。"""
29
+ if len(shape) == 1 and isinstance(shape[0], (tuple, list)):
30
+ shape = shape[0]
31
+ else:
32
+ shape = shape
33
+ result = arr._array.reshape(shape)
34
+ return ndarray._wrap(result, _dtype=getattr(arr, '_dtype', "float64"), _fields=getattr(arr, '_fields', None), _raw_data=getattr(arr, '_raw_data', None))
35
+
36
+ @staticmethod
37
+ def resize(arr, new_shape):
38
+ """改变数组形状和大小。"""
39
+ if isinstance(new_shape, int):
40
+ new_shape = (new_shape,)
41
+ elif isinstance(new_shape, list):
42
+ new_shape = tuple(new_shape)
43
+ arr._array.resize(new_shape)
44
+
45
+ @staticmethod
46
+ def ravel(arr, order='C'):
47
+ """将数组展平为一维。"""
48
+ if order == 'A' or order == 'K':
49
+ order = 'C'
50
+ return NdArrayMethods.flatten(arr, order)
51
+
52
+ @staticmethod
53
+ def flatten(arr, order='C'):
54
+ """展平数组为一维。"""
55
+ dtype = getattr(arr, '_dtype', "float64")
56
+ result = _core.flatten_full(arr._array, order)
57
+ return _wrap_result(result, dtype)
58
+
59
+ @staticmethod
60
+ def transpose(arr, *axes):
61
+ """转置数组。"""
62
+ dtype = getattr(arr, '_dtype', "float64")
63
+ fields = getattr(arr, '_fields', None)
64
+ raw = getattr(arr, '_raw_data', None)
65
+ if len(axes) == 0:
66
+ result = arr._array.T
67
+ else:
68
+ result = _core.transpose(arr._array)
69
+ return ndarray._wrap(result, _dtype=dtype, _fields=fields, _raw_data=raw)
70
+
71
+ @staticmethod
72
+ def swapaxes(arr, axis1, axis2):
73
+ """交换两个轴的位置。"""
74
+ dtype = getattr(arr, '_dtype', "float64")
75
+ fields = getattr(arr, '_fields', None)
76
+ raw_data = getattr(arr, '_raw_data', None)
77
+ result = _core.swapaxes(arr._array, axis1, axis2)
78
+ return ndarray._wrap(result, _dtype=dtype, _fields=fields, _raw_data=raw_data)
79
+
80
+ @staticmethod
81
+ def squeeze(arr, axis=None):
82
+ """移除长度为1的轴。"""
83
+ return _wrap_result(arr._array.squeeze())
84
+
85
+ @staticmethod
86
+ def max(arr, axis=None):
87
+ """返回数组的最大值。"""
88
+ result = arr._array.max(axis)
89
+ if axis is None and hasattr(result, 'tolist'):
90
+ return result.tolist()
91
+ return _wrap_result(result)
92
+
93
+ @staticmethod
94
+ def min(arr, axis=None):
95
+ """返回数组的最小值。"""
96
+ result = arr._array.min(axis)
97
+ if axis is None and hasattr(result, 'tolist'):
98
+ return result.tolist()
99
+ return _wrap_result(result)
100
+
101
+ @staticmethod
102
+ def mean(arr, axis=None):
103
+ """计算数组的平均值。"""
104
+ result = arr._array.mean(axis)
105
+ if axis is None and hasattr(result, 'tolist'):
106
+ return result.tolist()
107
+ return _wrap_result(result)
108
+
109
+ @staticmethod
110
+ def std(arr, axis=None):
111
+ """计算数组的标准差。"""
112
+ result = arr._array.std(axis)
113
+ if axis is None and hasattr(result, 'tolist'):
114
+ return result.tolist()
115
+ return _wrap_result(result)
116
+
117
+ @staticmethod
118
+ def var(arr, axis=None):
119
+ """计算数组的方差。"""
120
+ result = arr._array.var(axis)
121
+ if axis is None and hasattr(result, 'tolist'):
122
+ return result.tolist()
123
+ return _wrap_result(result)
124
+
125
+ @staticmethod
126
+ def sum(arr, axis=None):
127
+ """计算数组元素的和。"""
128
+ result = arr._array.sum(axis)
129
+ if axis is None and hasattr(result, 'tolist'):
130
+ return result.tolist()
131
+ return _wrap_result(result)
132
+
133
+ @staticmethod
134
+ def prod(arr, axis=None):
135
+ """计算数组元素的乘积。"""
136
+ result = arr._array.prod(axis)
137
+ if axis is None and hasattr(result, 'tolist'):
138
+ return result.tolist()
139
+ return _wrap_result(result)
140
+
141
+ @staticmethod
142
+ def cumsum(arr, axis=None):
143
+ """计算累积和。"""
144
+ result = arr._array.cumsum(axis)
145
+ return _wrap_result(result)
146
+
147
+ @staticmethod
148
+ def cumprod(arr, axis=None):
149
+ """计算累积乘积。"""
150
+ result = arr._array.cumprod(axis)
151
+ return _wrap_result(result)
152
+
153
+ @staticmethod
154
+ def argmax(arr, axis=None):
155
+ """返回最大值的索引。"""
156
+ return _wrap_result(_core.argmax_axis(arr._array, axis))
157
+
158
+ @staticmethod
159
+ def argmin(arr, axis=None):
160
+ """返回最小值的索引。"""
161
+ return _wrap_result(_core.argmin_axis(arr._array, axis))
162
+
163
+ @staticmethod
164
+ def argsort(arr, axis=-1):
165
+ """返回排序后的索引。"""
166
+ result = arr._array.argsort(axis)
167
+ return _wrap_result(result)
168
+
169
+ @staticmethod
170
+ def sort(arr, axis=-1):
171
+ """原地排序数组。"""
172
+ result = arr._array.sort(axis)
173
+ if hasattr(result, 'shape') and result.shape == arr.shape:
174
+ arr._array = result
175
+ else:
176
+ arr._array.data = result.data
177
+
178
+ @staticmethod
179
+ def diagonal(arr, offset=0, axis1=0, axis2=1):
180
+ """返回数组的对角线元素。"""
181
+ result = arr._array.diagonal(offset, axis1, axis2)
182
+ return _wrap_result(result)
183
+
184
+ @staticmethod
185
+ def trace(arr, offset=0, axis1=0, axis2=1):
186
+ """计算数组的迹(对角线元素之和)。"""
187
+ return arr._array.trace(offset, axis1, axis2)
188
+
189
+ @staticmethod
190
+ def fill(arr, value):
191
+ """用指定值填充数组。"""
192
+ arr._array.fill(value)
193
+
194
+ @staticmethod
195
+ def item(arr, *args):
196
+ """获取数组的单个元素。"""
197
+ return arr._array.item(*args)
198
+
199
+ @staticmethod
200
+ def tolist(arr):
201
+ """将数组转换为 Python 列表。"""
202
+ return arr._array.tolist()
203
+
204
+ @staticmethod
205
+ def take(arr, indices, axis=None):
206
+ """根据索引获取元素。"""
207
+ result = arr._array.take(_ensure(indices), axis)
208
+ return _wrap_result(result)
209
+
210
+ @staticmethod
211
+ def put(arr, indices, values):
212
+ """将值放入数组的指定位置。"""
213
+ arr._array.put(_ensure(indices), _ensure(values))
214
+
215
+ @staticmethod
216
+ def repeat(arr, repeats, axis=None):
217
+ """重复数组元素。"""
218
+ result = arr._array.repeat(repeats, axis)
219
+ return _wrap_result(result)
220
+
221
+ @staticmethod
222
+ def nonzero(arr):
223
+ """返回非零元素的索引。"""
224
+ raw = _core.nonzero_arrs(arr._array)
225
+ return tuple(ndarray._wrap(r) for r in raw)