2011-10-29 64 views
2

我有一個數學列表,其中我想用1替換所有2,其他所有變爲0.將列表中的所有值映射到2!到0

例如,

{0,1,2,3,2,3,4,5,2,2,6} 

- >

{0,0,1,0,1,0,0,0,1,1,0} 

我認爲這是可能使用全部替換,但什麼規則將實現這一目標?

謝謝!

回答

8

您可以將功能(Boole[2 == #]) &映射到列表上。

In[2]:= (Boole[2 == #]) & /@ {0, 1, 2, 3, 2, 3, 4, 5, 2, 2, 6} 
Out[2]= {0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0} 

不同部分的說明:

  • /@應用一個函數列表上的每個元件。
  • () &是用於anonymous functions的語法,並且該函數採用的參數的名稱爲#
  • BooleTrue/False轉換爲1/0

所以,在總,我們創建了一個匿名函數,該函數的輸入比較2,並給出要麼01。這個函數然後被映射到列表上。

+0

我已經在我的數學旅途所見這個「神祕符號」。你能解釋它的作用嗎? – VolatileStorm

+1

@VolatileStorm:它只是創建一個函數。在這種情況下,函數可以被定義爲:'isTwo [n_]:= Boole [2 == n];',然後我們可以用''Boole [2 ==#]'替換'在上面的例子中是「兩個」。 –

+2

而不是'()&',它是用於純函數的'# - &'對。 '()'只是設置執行的優先級,在這種情況下,沒有它就可以正常運行。 – abcd

5

您可以使用

Replace[{0, 1, 2, 3, 2, 3, 4, 5, 2, 2, 6}, {2 -> 1, _ -> 0}, 1] 

我用的Replace代替ReplaceAll到能夠告訴數學在這「級別」更換必須發生(的Replace最後一個參數)

+0

但是'MatchQ [{0,1,2,3,2,3,4,5,2,2,6},_]'返回'True',不是嗎? – acl

+0

抱歉大家,我在錯誤的帖子後糾正了錯誤,但是SO似乎有點慢,無法向所有觀衆發送最新版本。 – Szabolcs

1

嘗試

{0,1,2,3,2,3,4,5,2,2,6}/.{2->1,(x_/;MemberQ[Range[0,9],x])->0} 

它利用了012的以下屬性:

The first rule that applies to a particular part is used; 
no further rules are tried on that part, or on any of its subparts. 

這使得相當多的靈活性(如Range[]可以被改變成任何東西)。

3

如果列表是數字,我建議這樣的:

a = {0, 1, 2, 3, 2, 3, 4, 5, 2, 2, 6}; 

1 - Unitize[2 - a] 

由於時序數據已在答覆中介紹,我將添加自己的數據點。

按照外觀順序。在Windows 7上使用Mathematica 7。

首先,有稀疏的比賽(三三兩兩):

In[1]:= 
data = RandomInteger[{0, 40000}, 150000]; 
(Boole[2 == #]) & /@ data // timeAvg 
Replace[data, {2 -> 1, _ -> 0}, 1] // timeAvg 
1 - Unitize[2 - data] // timeAvg 
KroneckerDelta /@ (data - 2) // timeAvg 
[email protected][data, {2, 2}, {0, 0}] // timeAvg 

Out[2]= 0.0654 

Out[3]= 0.01684 

Out[4]= 0.0010224 

Out[5]= 0.106 

Out[6]= 0.00026944 

而且有密集的比賽:

In[1]:= 
data = RandomInteger[{0, 5}, 150000]; 
(Boole[2 == #]) & /@ data // timeAvg 
Replace[data, {2 -> 1, _ -> 0}, 1] // timeAvg 
1 - Unitize[2 - data] // timeAvg 
KroneckerDelta /@ (data - 2) // timeAvg 
[email protected][data, {2, 2}, {0, 0}] // timeAvg 

Out[2]= 0.0656 

Out[3]= 0.01308 

Out[4]= 0.0013968 

Out[5]= 0.0842 

Out[6]= 0.000648 
+2

這很好,因爲Unitize使用PossibleZeroQ進行比較 –

1

只是爲了好玩...

$v = {0, 1, 2, 3, 2, 3, 4, 5, 2, 2, 6}; 

KroneckerDelta /@ ($v - 2) 

(* returns {0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0} *) 
1

或者這

lst={0,1,2,3,2,3,4,5,2,2,6}; 
Clip[ 
    lst, 
    {2,2}, 
    {0,0} 
] 

它比所有其他的快100倍,除了Szabolcs之外,它的速度快了7倍。

Timing[Do[Clip[lst, {2, 2}, {0, 0}];, {10000}]] 
{0.021858, Null} 

Timing[Do[KroneckerDelta /@ (lst - 2), {10000}]] 
{0.131487, Null} 

Timing[Do[1 - Unitize[2 - lst], {10000}];]  
{0.214324, Null} 

Timing[Do[ 
    lst /. {2 -> 1, (x_ /; MemberQ[Range[0, 9], x]) -> 0};, {10000}]] 
{0.533773, Null} 

Timing[Do[Replace[lst, {2 -> 1, _ -> 0}, 1];, {10000}]] 
{0.066136, Null} 
+0

希望您不介意我將時間結果添加到您的答案 – Verbeia

+0

@Verbeia完全​​沒有。我隨機獲得不同的時間。讓我看看 – acl

+0

對於它的價值,這些計時是在一臺兩年前的2.5GHz Macbook Pro上完成的。 – Verbeia

0

只是爲了完整性起見,你也可以推出自己的轉換功能:

In[1]:= TwoToOne[2] = 1; TwoToOne[_] = 0; 
In[2]:= Map[TwoToOne, {0, 1, 2, 3, 2, 3, 4, 5, 2, 2, 6}] 
Out[2]:= {0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0}