JS宏案例:在wps编辑器中玩numpy

打印 上一主题 下一主题

主题 890|帖子 890|积分 2670

NumPy 是 Python 中用于科学计算的一个基础库,它提供了大量的数学函数工具,尤其是用于高效处置处罚大型多维数组和矩阵。NumPy 是 Python 数据分析、机器学习、科学计算等领域中不可或缺的一部分。
然,在wps的js宏编辑器中,并没有这样一个模块或是全局对象,但是,题目不大,我们可以手搓一个。不外,要使用JS完全模拟python中的numpy是比较困难的,工作量也非常的大,我们可以适当简化一下,如只对常用方法和属性进行模拟。
一、自定义错误

  1. class DimensionError extends Error {
  2.         constructor(message) {
  3.                 super(message);
  4.                 this.name = "维度错误";
  5.         }
  6. }
  7. class ValueError extends Error {
  8.         constructor(message) {
  9.                 super(message);
  10.                 this.name = "值错误";
  11.         }
  12. }
复制代码
上述代码中,定义了一个维度错误和值错误,是py中numpy模块中常见的两种错误。
二、构造Numpy全局对象

1、示例代码:

  1. class Numpy {
  2.        
  3.         constructor(array) {
  4.                 if (array !== undefined && !Array.isArray(array)) {
  5.                         throw new TypeError("the parm array must be array.");
  6.                 }
  7.                 this.#_array = array;
  8.         }
  9.        
  10.         // 获取数组维度
  11.         get ndim() {
  12.                 let n = 0;
  13.                 let array = this.#_array;
  14.                 while (Array.isArray(array)) {
  15.                         n++;
  16.                         array = array[0];
  17.                 }
  18.                 return n;
  19.         }
  20.        
  21.         // 返回数组的维度,是一个整数数组,表示每个维度中数组的大小。对于具有 n 行和 m 列的矩阵,shape 将是 [n, m]。
  22.         get shape() {
  23.                 let result = [];
  24.                 let n = this.ndim;
  25.                 let array = this.#_array;
  26.                 while (n > 0) {
  27.                         result.push(array.length);
  28.                         array = array[0];
  29.                         n--;
  30.                 }
  31.                 return result;
  32.         }
  33.        
  34.         // 返回数组中所有元素的个数
  35.         get size() {
  36.                 let arr = this.shape;
  37.                 let product = 1;
  38.                 for (let i = 0; i < arr.length; i++) {
  39.                         product *= arr[i];
  40.                 }
  41.                 return product;
  42.         }
  43.        
  44.         // 转置
  45.         get T() {
  46.                 return this.#_transpose(this.#_array);
  47.         }
  48.        
  49.         get random() {
  50.                 // random对象
  51.                 let self = this;
  52.                 return {
  53.                         rand: function(shape) {
  54.                                 // 生成shape形状的随机数组,数值用随机数填充
  55.                                 if (shape === undefined || shape === null) return Math.random();
  56.                                 if (!Array.isArray(shape)) throw new TypeError("param shape must be array.");
  57.                                 if (!shape.every(i => Number.isInteger(i)))  throw new TypeError("shape must be array of integer.");
  58.                                 return self.full(shape, () => Math.random());
  59.                         },
  60.                         randn: function(shape) {
  61.                                 // 随机正态分布
  62.                             if (typeof shape === "number") shape = [shape]; // 如果 shape 是数字,转换为数组
  63.                             if (!Array.isArray(shape)) throw new TypeError("shape must be a number or array");
  64.                             const totalElements = shape.reduce((acc, val) => acc * val, 1); // 计算总元素个数
  65.                             const result = Array.from({ length: totalElements }, () => self.#_randn()); // 生成随机数
  66.                             // 将一维数组转换为多维数组
  67.                             function reshape(arr, shape) {
  68.                                 if (shape.length === 1) return arr;
  69.                                 const [currentDim, ...remainingDims] = shape;
  70.                                 const result = [];
  71.                                 const chunkSize = arr.length / currentDim;
  72.                                 for (let i = 0; i < currentDim; i++) {
  73.                                     result.push(reshape(arr.slice(i * chunkSize, (i + 1) * chunkSize), remainingDims));
  74.                                 }
  75.                                 return result;
  76.                             }
  77.                             return new Numpy(reshape(result, shape));
  78.                         },
  79.                         randint: function(low, high = null, size = null) {
  80.                             if (high === null) {
  81.                                 high = low;
  82.                                 low = 0;
  83.                             }
  84.                             if (low >= high) throw new ValueError("low must be less than high");
  85.                             // 单个随机整数
  86.                             function getRandomInt(low, high) {
  87.                                      return Math.floor(Math.random() * (high - low)) + low;
  88.                             }
  89.                             // 如果 size 未提供,返回单个随机数
  90.                             if (size === null) return getRandomInt(low, high);
  91.                             // 如果 size 是数字,转换为数组
  92.                             if (typeof size === "number") size = [size];
  93.                             if (!Array.isArray(size)) throw new TypeError("size must be a number or array");
  94.                             const totalElements = size.reduce((acc, val) => acc * val, 1);
  95.                             const result = Array.from({ length: totalElements }, () => getRandomInt(low, high));
  96.                             function reshape(arr, shape) {
  97.                                 if (shape.length === 1) return arr;
  98.                                 const [currentDim, ...remainingDims] = shape;
  99.                                 const result = [];
  100.                                 const chunkSize = arr.length / currentDim;
  101.                                 for (let i = 0; i < currentDim; i++) {
  102.                                     result.push(reshape(arr.slice(i * chunkSize, (i + 1) * chunkSize), remainingDims));
  103.                                 }
  104.                                 return result;
  105.                             }
  106.                             return new Numpy(reshape(result, size));
  107.                         },
  108.                         choice: function(a, size = null, replace = true, p = null) {
  109.                                     if (typeof a === "number") {
  110.                                         a = Array.from({ length: a }, (_, i) => i); // 如果 a 是数字,生成 range(a)
  111.                                     }
  112.                                     if (!Array.isArray(a)) throw new TypeError("a must be a number or array");
  113.                                     if (p !== null) {
  114.                                         if (!Array.isArray(p)) throw new TypeError("p must be an array");
  115.                                         if (p.length !== a.length) throw new ValueError("a and p must have the same length");
  116.                                         if (p.some(prob => prob < 0)) throw new ValueError("probabilities must be non-negative");
  117.                                         const totalProb = p.reduce((acc, val) => acc + val, 0);
  118.                                         if (Math.abs(totalProb - 1) > 1e-6) throw new ValueError("probabilities must sum to 1");
  119.                                     }
  120.                                     // 如果 size 未提供,返回单个随机元素
  121.                                     if (size === null) {
  122.                                         if (p === null) {
  123.                                             return a[Math.floor(Math.random() * a.length)];
  124.                                         } else {
  125.                                             const rand = Math.random();
  126.                                             let cumulativeProb = 0;
  127.                                             for (let i = 0; i < a.length; i++) {
  128.                                                 cumulativeProb += p[i];
  129.                                                 if (rand < cumulativeProb) return a[i];
  130.                                             }
  131.                                         }
  132.                                     }
  133.                                     // 如果 size 是数字,转换为数组
  134.                                     if (typeof size === "number") size = [size];
  135.                                     if (!Array.isArray(size)) throw new TypeError("size must be a number or array");
  136.                                     const totalElements = size.reduce((acc, val) => acc * val, 1);
  137.                                     const result = [];
  138.                                     for (let i = 0; i < totalElements; i++) {
  139.                                         if (p === null) {
  140.                                             const randomIndex = Math.floor(Math.random() * a.length);
  141.                                             result.push(a[randomIndex]);
  142.                                             if (!replace) a.splice(randomIndex, 1); // 如果不允许重复,移除已选元素
  143.                                         } else {
  144.                                             const rand = Math.random();
  145.                                             let cumulativeProb 
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

饭宝

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表