2011-10-29 34 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}