我有一個數學列表,其中我想用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}
我認爲這是可能使用全部替換,但什麼規則將實現這一目標?
謝謝!
我有一個數學列表,其中我想用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}
我認爲這是可能使用全部替換,但什麼規則將實現這一目標?
謝謝!
您可以將功能(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的語法,並且該函數採用的參數的名稱爲#
。Boole
將True
/False
轉換爲1
/0
。所以,在總,我們創建了一個匿名函數,該函數的輸入比較2
,並給出要麼0
或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[]
可以被改變成任何東西)。
如果列表是數字,我建議這樣的:
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
這很好,因爲Unitize使用PossibleZeroQ進行比較 –
只是爲了好玩...
$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} *)
或者這
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}
只是爲了完整性起見,你也可以推出自己的轉換功能:
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}
我已經在我的數學旅途所見這個「神祕符號」。你能解釋它的作用嗎? – VolatileStorm
@VolatileStorm:它只是創建一個函數。在這種情況下,函數可以被定義爲:'isTwo [n_]:= Boole [2 == n];',然後我們可以用''Boole [2 ==#]'替換'在上面的例子中是「兩個」。 –
而不是'()&',它是用於純函數的'# - &'對。 '()'只是設置執行的優先級,在這種情況下,沒有它就可以正常運行。 – abcd