Re: logical indexing using more than one variable in a pure function
- To: mathgroup at smc.vnet.net
- Subject: [mg53360] Re: [mg53342] logical indexing using more than one variable in a pure function
- From: "Wolf, Hartmut" <Hartmut.Wolf at t-systems.com>
- Date: Sat, 8 Jan 2005 02:39:27 -0500 (EST)
- Sender: owner-wri-mathgroup at wolfram.com
>-----Original Message----- >From: Ben Barrowes [mailto:barrowes at alum.mit.edu] To: mathgroup at smc.vnet.net >Sent: Friday, January 07, 2005 4:01 AM >Subject: [mg53360] [mg53342] logical indexing using more than one variable in a >pure function > >I am trying to pick out values from a matrix using a logical mask, i.e. >using logical indexing. > > >I wish the following: >x = {2, 3, 4, 5, 6} >y = {True, False, False, True, True} >x[[y]] >would produce: >{2,5,6} >but instead it produces: >\!\(\* > RowBox[{\(Part::"pspec"\), \(\(:\)\(\ \)\), "\<\"Part specification >\ \\!\\({True, False, False, True, True}\\) is neither an integer nor a >list of \ integers. >\\!\\(\\*ButtonBox[\\\"More\[Ellipsis]\\\", \ >ButtonStyle->\\\"RefGuideLinkText\\\", ButtonFrame->None, \ >ButtonData:>\\\"General::pspec\\\"]\\)\"\>"}]\) >{2, 3, 4, 5, 6}\[LeftDoubleBracket]{True, False, False, True, > True}\[RightDoubleBracket] > > >Here are some working examples when the mask depends upon only one >variable: > >pick out values in x > 4 >Select[x, (#1 > 4 &)] >{5, 6} > >BooleanSelect seems to do what I want if I have a logical mask already: ><< Statistics`DataManipulation` >BooleanSelect[x, y] >{2, 5, 6} >And now in 5.1, "Pick" does the same thing as BooleanSelect. >But how can I do this in one line? (no need to define y >explicitly) Something like: >Pick[x,x>3] > > > >This seems to work for cases: >Cases[x, x_ /; x > 3] >{4, 5, 6} >and similarly for select: >Select[x, # > 3 &] >{4, 5, 6} > > >But if I have a second List: >x1 = {6, 5, 4, 3, 2} > >How would I index x based on a logical operation on both x and x1? >I hoped something like this would work: >Pick[x,x>x1] >or >Cases[x, {x_,x1_} /; x>x1] >{} >But only x is provided to the pattern match, not {x_,x1_}. > >Or maybe a better Select statement. But how do I make the pure function >accept two arguments? > >For that matter, how can I perform an element by element logical >operation on a list? For example, I would like: >x>3 >to return >{False,False,True,True,True} >instead of >{2, 3, 4, 5, 6} > 3 >and >x>x1 >to return >{False,False,False,True,True} >instead of >{2, 3, 4, 5, 6} > {6, 5, 4, 3, 2} >will something like: >#1 > #2 &, x, x1 >work? > >I would appreciate any suggestions, >Ben > > Ben, To answer your last question first: In[13]:= Thread[{2,3,4,5,6} > 3] Out[13]= {False,False,True,True,True} In[10]:= Thread[x > x1] Out[10]= {False, False, False, True, True} In[12]:= BooleanSelect[x, Thread[x > x1]] Out[12]= {5, 6} Try this with Pick (I just temporarily ran out ouf pickers). -- Hartmut Wolf P.S. for higher dimensions proceed along the lines In[21]:= << DiscreteMath`Permutations` In[22]:= xx = Partition[Range[16], 4] Out[22]= {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15, 16}} In[24]:= xx1 = Partition[RandomPermutation[16], 4] Out[24]= {{1, 5, 14, 2}, {4, 6, 13, 9}, {8, 15, 16, 11}, {7, 10, 3, 12}} In[32]:= yy = MapThread[Greater, {xx, xx1}, 2] Out[32]= {{False, False, False, True}, {True, False, False, False}, {True, False, False, True}, {True, True, True, True}} In[33]:= MapThread[BooleanSelect, {xx, yy}] Out[33]= {{4}, {5}, {9, 12}, {13, 14, 15, 16}} Or if you prefer (as I do): In[36]:= MapThread[If[#2, #1, Unevaluated[Sequence[]]] &, {xx, yy}, 2] Out[36]= {{4}, {5}, {9, 12}, {13, 14, 15, 16}}