项目 1
第 1 项中具有挑战性的部分挑战10不是代码,而是分位数定义的复杂性。 首先,让我们保持事物分布独立,并使用值的排名顺序而不是直接使用值。 也就是说,我们按升序对值进行排序,并根据它们按顺序出现的位置对它们进行编号。 我们需要决定如何处理关系。 我们可以继续按顺序对它们进行排名或给它们相同的值。 前者的缺点是我们可能会在多个组中出现相同的值。 后一种方法的缺点是每组的项目数量可能不太平衡。 这两种方法分别对应排行和排名并列JSL 功能。 我们还没有讨论在第二种方法中赋予关系什么价值。 我们可以给它们所有下一个连续的排名顺序值。 或者,我们可以对顺序排名的值进行平均。 在这两种情况下,我们可能希望为下一个连续的非绑定值提供如果没有绑定时它将获得的排名。 排名并列平均排名,为了简单起见,我们将使用它。
下一个问题是如何划分组。 我们可以尝试尽可能平均地分配它们。 一个简单的方法是按顺序对关系进行排名,至少放置地面(氮/ G )每组中的项目(其中氮它是项目总数和G是分位数组的数量)。 我们必须决定把氮– G *地面(氮/ G ) < G附加值。 下面的代码简单而整洁地处理了所有这些:
天花板(排名(inVec)/(N 行(inVec)/定量))
在哪里内维克是输入(列)向量并且定量分位数组的数量。
上面的代码可能会导致绑定值被分割到不同的组中。 为了避免这种情况,我们可以替换排行和排名并列。 完整功能的示例如下:
quantileGroup = Function({inVec,quant=10,method=1},{outVec,sumTblRef,ranks},
inVec = Shape(inVec,N Row(invec)*N Col(inVec),1);
If(method ==1,
outVec = Ceiling(Ranking(inVec)/(N Row(inVec)/quant)),
outVec = Ceiling(Ranking Tie(inVec)/(N Row(inVec)/quant))
);
outVec;
);
项目2
我们可以通过多种不同的方式来聚合低计数组:通过观察的绝对数量、观察的相对数量(例如,计数小于最大组的 10% 的组)、固定组的总数等。有它的优点和缺点。 为了提供灵活的解决方案,我选择采用一种交互式和可视化的方法,通过可使用滑块进行调整的条形图进行管理。 这样,我可以前后移动滑块,直到找到看起来不错的组分布。 困难在于当组数量很大时如何编写快速的代码。 为了简单起见,我想使用数据表操作和平台(使用自动重新计算打开)。 下面是之前和之后的示例:
前

后

一般来说,此代码的工作原理是根据组构建汇总表并使用组计数( N 行列)作为频率多变的。 这避免了更新原始表中的值的需要,原始表可能要大得多。 代码可以在中找到聚合组。 除了计数(排名)的向量排名顺序之外,来自摘要的原始组值的列表也存储在全局变量组中。 移动滑块运行聚合低计数函数,其中请求组数( n组)是根据滑块的位置传递的。 组的数量可以很容易地从排名向量中选择。 例如,如果总共需要10个组,则将具有等级10或更高的任何原始组的值设置为聚合组值(例如,“其他”),而所有其他组保持相同。 由于表已排序,因此只需要更改第 10 行以后的值。
项目 3 / 项目 4
我创建此项目的动机是作为项目 4 的先驱。 在关联数组 (AA) 中查找内容比使用要快得多洛克。 使用 209,405 个单词构建 AA单词表.JMP在我的电脑上花了不到 12 秒。 下表显示了使用以下任一方法从表中查找随机单词列表的时间洛克或 AA。
N 字
|
洛克(秒)
|
关联数组(秒)
|
1
|
0.19
|
0.000045
|
5
|
0.91
|
0.000127
|
10
|
1.78
|
0.000244
|
25
|
4.51
|
0.000592
|
50
|
9.11
|
0.001019
|
70
|
12.47
|
0.001454
|
100
|
17.82
|
0.002155
|
对于超过 70 个单词的列表,建立 AA 是值得的。 我用来测试这两种方法的代码位于Loc vs AA.JSL 。
使用 AA 作为可搜索数据结构有优点和缺点。 从好的方面来说,您可以将任何值与 AA 密钥关联,包括其他 AA。 缺点是键必须是唯一的(在我的选择中没什么大不了的),更重要的是,如果搜索值不在键列表中,则必须增强搜索过程。 这就是说,当所有可能的搜索值先验已知时,实现相对容易,但如果不先验已知,则实现会有点棘手。 这并不意味着我们不能使用它们;而是意味着我们不能使用它们。我们只需要变得更狡猾一点。 像下面的代码这样的东西适用于第 3 项标记的帖子中提到的案例。 在某些情况下有点麻烦并且可能更慢,但非常灵活。 只需修改关联数组的内容,它就可以轻松适应查找字典发生变化的情况。
aaMap = Associative Array(
{"1","2","3","4","5","6","7","8","9","0","M","K"},
{"1","2","3","4","5","6","7","8","9","0","e6","e3"}
);
findAndReplace = Function({inList,aaMap},
outNums = Transform Each({nextString},inList,Output("Matrix"),
nextChars = Items(nextString,"");
Num(Concat Items(Transform Each({nextChar},nextChars,aaMap[nextChar]),""));
);
outNums
);
如果我想解决一些更一般、更大的问题,比如为《悲惨世界》英文译本中出现的所有单词建立一本字典,该怎么办? 首先,我们假设一个单词仅由字母字符组成,可能包括标准 ASCII 字符集之外的字母(例如,带有变音符号的字母)。 其他一切都是分隔符。 这里的挑战是我们不确定可能会遇到什么分隔字符。 由于我们知道单词由哪些字符组成,因此我们可以假设如果它不在列表中,那么它就是一个分隔符。
模式匹配拥有完美的工具来查找我们将用来构建词典的单词:帕特·斯潘和拍拍休息。我们可以使用字,但是我们必须检查每个项目是否有嵌入的分隔符。 使用模式匹配可以让我们一步完成所有事情。 代码如下。 整个过程持续了8到9秒。 要将代码应用于不同的文本,可能需要进行一些微调,例如包含附加字符并将文件保存为不同的编码(我使用 utf-16 来捕获扩展 ASCII 字符)。 我很感激@Craige_Hales在我努力让它发挥作用后帮助我解决这个问题。 《悲惨世界》的文本文件是从古腾堡计划。 你可以找到它这里。
bigText = Load Text File("Les Misérables.txt");
aaLookup = Associative Array();
letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZé´É";
wordLoc = 0;
Pat Match(bigText,
Pat Repeat(
(
Pat Pos() >> nextLoc
+ Pat Span( letters ) >> nextWord
+ Pat Test(
Try(
Insert Into(aaLookup[Lowercase(nextWord)],nextLoc),
aaLookup<<INSERT></INSERT>
好的! 这尝试() 构造您用于关联数组的结构插入()可能比首先测试现有元素更快。
当我还年轻,进入读书圈时,我的一个经常旅行的朋友读到了一篇带有这个词的文章优胜美地,我从来没有遇到过。 我记得我被他的四音节发音吓了一跳,并注意到老师很惊喜。
多年后,有人告诉我我可以说跛脚是罗布并把剧名起得足够正确,以免引起注意。