2014-05-04 37 views
0

我正在使用相當大的矩陣,我想過濾出真實的值。使用Mathematica過濾實際值

{999, "na", Times[w, 1], 2.5, Indeterminate, 6.0} 

應該成爲

{"na", "na", "na", 2.5, "na", 6.0} 

它與

AnyMatrix /. {_If -> "na", _Last -> "na", _Mean -> "na", _Plus -> 
    "na", _Round -> "na", _Times -> "na", _Integer -> 
    "na", _DirectedInfinity -> "na", Indeterminate -> "na"} 

但這可能不是很長的時間效率。另外,我無法預測未來會出現哪些其他非真實的形式。

有沒有更聰明的方法來做到這一點?

回答

0

這應該是有效的:

lst = {999, "na", Times[w, 1], 2.5, Indeterminate, 6.0}; 
pos = Position[lst, _Real]; 
ReplacePart[ConstantArray["na", Length[lst]], 
Thread[Rule[Flatten[pos], Extract[lst, pos]]]] 

(*=> {"na", "na", "na", 2.5, "na", 6.} *) 

更高效:

lst = {999, "na", Times[w, 1], 2.5, Indeterminate, 6.0}; 
pos = Position[lst, _Real]; 
SparseArray[Thread[Rule[Flatten[pos], Extract[lst, pos]]], 
    Length[lst], "na"] // Normal 

(*=> {"na", "na", "na", 2.5, "na", 6.} *) 

來說,簡化的版本(比以前的嘗試更安全,也很有效):

lst = {999, "na", Times[w, 1], 2.5, Indeterminate, 6.0}; 
Replace[lst, {x_Real :> x, x_ -> "na"}, {1}] 

(*=> {"na", "na", "na", 2.5, "na", 6.} *) 
0

的doc中文教程查找匹配模式的表達式描述了幾種識別和選擇列表元素的方法。

案例是一個候選函數,它將以最簡單的形式挑出並返回匹配模式的列表元素,這裏是Real。

lst = {999, "na", Times[w, 1], 2.5, Indeterminate, 6.0}; 
Cases[lst,s_Real] 

(* Out-> {2.5,6.} *) 

但是,如果你想保留數據的原始結構,那麼你會希望每個元素進行分類,保存它,如果它符合,如果它不會取代它。您可以通過將替換規則提供給Cases參數列表來實現此目的,這些規則可以通過模式,條件和計算以常規方式構建。以下是制定產生期望結果的替代規則的透明方式。

Cases[lst, s_ :> If[Head[s] === Real, s, "na"]] 

(* Out -> {"na", "na", "na", 2.5, "na", 6.} *) 

默認情況下,例作用在列表的頂部電平 - 適合在這種情況下 - 但是對於更復雜的數據結構,所述水平活動可以以通常的方式來指定。

+1

你能花一點時間來解釋你在這裏做了什麼,以便OP和後代的SO'ers能夠從你的文章中學習嗎?標記爲 –

+0

。這個答案可能是正確的,但它需要更充實。 –

+0

@Fred - 即使在大型n級矩陣中,您的第二種方法也是超快速的。我想知道它爲什麼起作用,因爲人們應該認爲你的編碼也會取代列表頭,所以我期望看到「na」[「na」,...,6。] ??? – eldo