ToB企服应用市场:ToB评测及商务社交产业平台
标题:
JS宏案例:在wps编辑器中玩numpy
[打印本页]
作者:
饭宝
时间:
8 小时前
标题:
JS宏案例:在wps编辑器中玩numpy
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企服之家,中国第一个企服评测及商务社交产业平台。
欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/)
Powered by Discuz! X3.4