我有一个数学列表,其中我想用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