NumPy 是 Python 中用于科学计算的一个基础库,它提供了大量的数学函数工具,尤其是用于高效处置处罚大型多维数组和矩阵。NumPy 是 Python 数据分析、机器学习、科学计算等领域中不可或缺的一部分。
然,在wps的js宏编辑器中,并没有这样一个模块或是全局对象,但是,题目不大,我们可以手搓一个。不外,要使用JS完全模拟python中的numpy是比较困难的,工作量也非常的大,我们可以适当简化一下,如只对常用方法和属性进行模拟。
一、自定义错误
- class DimensionError extends Error {
- constructor(message) {
- super(message);
- this.name = "维度错误";
- }
- }
- class ValueError extends Error {
- constructor(message) {
- super(message);
- this.name = "值错误";
- }
- }
复制代码 上述代码中,定义了一个维度错误和值错误,是py中numpy模块中常见的两种错误。
二、构造Numpy全局对象
1、示例代码:
- class Numpy {
-
- constructor(array) {
- if (array !== undefined && !Array.isArray(array)) {
- throw new TypeError("the parm array must be array.");
- }
- this.#_array = array;
- }
-
- // 获取数组维度
- get ndim() {
- let n = 0;
- let array = this.#_array;
- while (Array.isArray(array)) {
- n++;
- array = array[0];
- }
- return n;
- }
-
- // 返回数组的维度,是一个整数数组,表示每个维度中数组的大小。对于具有 n 行和 m 列的矩阵,shape 将是 [n, m]。
- get shape() {
- let result = [];
- let n = this.ndim;
- let array = this.#_array;
- while (n > 0) {
- result.push(array.length);
- array = array[0];
- n--;
- }
- return result;
- }
-
- // 返回数组中所有元素的个数
- get size() {
- let arr = this.shape;
- let product = 1;
- for (let i = 0; i < arr.length; i++) {
- product *= arr[i];
- }
- return product;
- }
-
- // 转置
- get T() {
- return this.#_transpose(this.#_array);
- }
-
- get random() {
- // random对象
- let self = this;
- return {
- rand: function(shape) {
- // 生成shape形状的随机数组,数值用随机数填充
- if (shape === undefined || shape === null) return Math.random();
- if (!Array.isArray(shape)) throw new TypeError("param shape must be array.");
- if (!shape.every(i => Number.isInteger(i))) throw new TypeError("shape must be array of integer.");
- return self.full(shape, () => Math.random());
- },
- randn: function(shape) {
- // 随机正态分布
- if (typeof shape === "number") shape = [shape]; // 如果 shape 是数字,转换为数组
- if (!Array.isArray(shape)) throw new TypeError("shape must be a number or array");
- const totalElements = shape.reduce((acc, val) => acc * val, 1); // 计算总元素个数
- const result = Array.from({ length: totalElements }, () => self.#_randn()); // 生成随机数
- // 将一维数组转换为多维数组
- function reshape(arr, shape) {
- if (shape.length === 1) return arr;
- const [currentDim, ...remainingDims] = shape;
- const result = [];
- const chunkSize = arr.length / currentDim;
- for (let i = 0; i < currentDim; i++) {
- result.push(reshape(arr.slice(i * chunkSize, (i + 1) * chunkSize), remainingDims));
- }
- return result;
- }
- return new Numpy(reshape(result, shape));
- },
- randint: function(low, high = null, size = null) {
- if (high === null) {
- high = low;
- low = 0;
- }
- if (low >= high) throw new ValueError("low must be less than high");
- // 单个随机整数
- function getRandomInt(low, high) {
- return Math.floor(Math.random() * (high - low)) + low;
- }
- // 如果 size 未提供,返回单个随机数
- if (size === null) return getRandomInt(low, high);
- // 如果 size 是数字,转换为数组
- if (typeof size === "number") size = [size];
- if (!Array.isArray(size)) throw new TypeError("size must be a number or array");
- const totalElements = size.reduce((acc, val) => acc * val, 1);
- const result = Array.from({ length: totalElements }, () => getRandomInt(low, high));
- function reshape(arr, shape) {
- if (shape.length === 1) return arr;
- const [currentDim, ...remainingDims] = shape;
- const result = [];
- const chunkSize = arr.length / currentDim;
- for (let i = 0; i < currentDim; i++) {
- result.push(reshape(arr.slice(i * chunkSize, (i + 1) * chunkSize), remainingDims));
- }
- return result;
- }
- return new Numpy(reshape(result, size));
- },
- choice: function(a, size = null, replace = true, p = null) {
- if (typeof a === "number") {
- a = Array.from({ length: a }, (_, i) => i); // 如果 a 是数字,生成 range(a)
- }
- if (!Array.isArray(a)) throw new TypeError("a must be a number or array");
- if (p !== null) {
- if (!Array.isArray(p)) throw new TypeError("p must be an array");
- if (p.length !== a.length) throw new ValueError("a and p must have the same length");
- if (p.some(prob => prob < 0)) throw new ValueError("probabilities must be non-negative");
- const totalProb = p.reduce((acc, val) => acc + val, 0);
- if (Math.abs(totalProb - 1) > 1e-6) throw new ValueError("probabilities must sum to 1");
- }
- // 如果 size 未提供,返回单个随机元素
- if (size === null) {
- if (p === null) {
- return a[Math.floor(Math.random() * a.length)];
- } else {
- const rand = Math.random();
- let cumulativeProb = 0;
- for (let i = 0; i < a.length; i++) {
- cumulativeProb += p[i];
- if (rand < cumulativeProb) return a[i];
- }
- }
- }
- // 如果 size 是数字,转换为数组
- if (typeof size === "number") size = [size];
- if (!Array.isArray(size)) throw new TypeError("size must be a number or array");
- const totalElements = size.reduce((acc, val) => acc * val, 1);
- const result = [];
- for (let i = 0; i < totalElements; i++) {
- if (p === null) {
- const randomIndex = Math.floor(Math.random() * a.length);
- result.push(a[randomIndex]);
- if (!replace) a.splice(randomIndex, 1); // 如果不允许重复,移除已选元素
- } else {
- const rand = Math.random();
- let cumulativeProb
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |