項目 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>
好的! 這嘗試() 構造您用於關聯數組的結構插入()可能比首先測試現有元素更快。
當我還年輕,進入讀書圈時,我的一個經常旅行的朋友讀到了一篇帶有這個詞的文章優勝美地,我從來沒有遇到過。 我記得我被他的四音節發音嚇了一跳,並註意到老師很驚喜。
多年後,有人告訴我我可以說跛腳是羅布並把劇名起得足夠正確,以免引起注意。