Tag Info

Hot answers tagged

26

n = 100; (*number of points*) s = RandomSample@Range@n; (*the initial set*) (*some aux functions*) head[{x_, xs___}] := Select[{xs}, # <= x &]; tail[{x_, xs___}] := Select[{xs}, # > x &]; (*qsort function modified for sowing the information needed*) qsort[{}] = {}; qsort[l : {x_, ___}] := Module[{lh, lt}, (Sow@{l, lh = head@l, x, lt = tail@l}; ...


25

You can use combination of Part and Ordering as list1[[ Ordering @ list2 ]] to sort list1 in the order of list2. Examples: {list1, list2, list3} = {{1, 3, 2}, {a, b, c}, {x, y, z}}; list2[[ Ordering @ list1 ]] gives {a, c, b} and list3[[ Ordering @ list1 ]] gives {x, z, y} EDIT: Using with lists of lists, to sort the entire array based on the ...


25

This is probably because by default Sort doesn't just use numerical values, it includes structure information as well. From the doc: Numeric expressions are sorted by structure as well as numerical value: In[1]:= Sort[{Sqrt[2], 1, 2, 1/Sqrt[2]}] Out[1]= {1, 2, 1/Sqrt[2], Sqrt[2]} Sort by numerical value only: In[2]:= Sort[{Sqrt[2], 1, 2, ...


24

Here is my contribution, which has the following benefits over previous answers: It sorts both numbers and non-numeric structures You can sort any column (not just the first, followed by the second, etc) You can sort in either direction (ascending / descending) Original order is kept: if you sort on the second column, the first entry will follow the order ...


20

This is implemented in SortBy: Because this function does not perform a pairwise compare, you would need to be able to recast your sort function to produce a canonical ordering. On the upside, if you are able to do so it will be far more efficient than Sort. f1 = Mod[#, 4] &; f2 = Mod[#, 7] &; SortBy[Range@10, {f1, f2}] {#, f1@#, f2@#} & ...


19

If you want to keep the rows and your preferences of ordering is first ascending, second descending and third ascending, you can use SortBy: SortBy[data, {#[[1]],-#[[2]],#[[3]]}&]


19

lists = {list1, list2, list3} = {{1, 3, 2}, {a, b, c}, {x, y, z}}; Another option SortBy[lists\[Transpose], First]\[Transpose] {{1, 2, 3}, {a, c, b}, {x, z, y}}


18

Yes, there is! Szabolcs showed a use of GatherBy in an inverted fashion as a substitute for a conventional decorate-and-sort. It proved both syntactically and computationally efficient. By using that method in place of the decorate-and-sort in this application we can use Ordering directly, and also eliminate Part which was needed to strip the decoration: ...


16

Maybe Partition[Sort@list, 2, 1] giving {{1, 3}, {3, 4}, {4, 5}, {5, 7}}


16

This is short: Last /@ Sort[{Characters@#, #} & /@ names] {"~/Hex_6.dat", "~/Hex_12.dat", "~/Hex_24.dat", "~/Hex_48.dat", "~/Hex_96.dat", "~/Hex_192.dat"} Alternatively: Last /@ Sort[{ToExpression[StringJoin[Select[Characters@#, DigitQ]]], #} & /@ names]


15

I think this question admits an elegant solution. Here is my attempt: define a special wrapper: ClearAll[sortFun]; sortFun /: SortBy[expr_, sortFun[funs_List, partFun_]] := SortBy[expr, Map[Composition[#, partFun] &, funs]]; Now, mySort := {StringTake[#, 1] &, ToExpression@StringDrop[#, 1] &} and SortBy[{"T3","T14","T1","E2"}, ...


15

With: dat = {{10, b, 30}, {100, a, 40}, {1000, b, 10}, {1000, b, 70}, {100, b, 20}, {10, b, 70}}; Perhaps most directly: Cases[dat, {_, _, Max@dat[[All, 3]]}] More approaches: Last @ SplitBy[SortBy[dat, {#[[3]] &}], #[[3]] &] Pick[dat, #, Max@#] &@dat[[All, 3]] Reap[Fold[(If[#2[[3]] >= #, Sow@#2]; #2[[3]]) &, dat]][[2, 1]] Of ...


15

Rather than it being "too big" for the pattern matcher, the problem here is because of the use of //. which applies the rule repeatedly till the result no longer changes (i.e. the list is sorted). In other words, the issue is that of the complexity of the algorithm you're using (//. with ___) rather than the programming paradigm that you've chosen (pattern ...


15

You could do this: GatherBy[list, Last][[All, 1]] ~SortBy~ Last (* {{d, 3}, {b, 3.04}, {a, 3.1}} *)


14

No, this is not a bug, and Ordering does not give a wrong answer. Quoting the documentation of Sort, Sort[list,p] applies the function p to pairs of elements in list to determine whether they are in order. The default function p is OrderedQ[{#1, #2}] &. As you can see, Sort (and Ordering) compares using OrderedQ, not Less. OrderedQ uses a ...


13

Ordering and Part is more efficient than SortBy and Transpose and it can also be done in one pass as I will demonstrate. I create three lists of different type as described in the question: a = RandomInteger[999, 500]; b = RandomReal[1, 500]; c = CharacterRange["a", "z"] ~RandomChoice~ 500; I use the timeAvg function for testing: SortBy[{a, b, ...


13

Using Simon's data: In[6]:= datelist = {"29/02/2008", "15/12/2007", "06/09/2007", "06/10/2008", "05/03/2007", "24/01/2010", "19/06/2009", "03/11/2009", "02/02/2010", "25/12/2009"}; We can just sort the data by the absolute time: In[7]:= SortBy[datelist, AbsoluteTime[{#, {"Day", "Month", "Year"}}] &] Out[7]= {"05/03/2007", "06/09/2007", ...


13

You can use ReplaceList with a helper function which has the Orderless attribute: ClearAll[f]; SetAttributes[f, Orderless]; ReplaceList[f[a, b, c], f[a___, b___, c___] :> {{a}, {b}, {c}}] // DeleteCases[#, {}, -1] & // Union // Column The DeleteCases and Union are required because the output from ReplaceList includes the empty list {} as a ...


12

A simple string-based approach is to swap the order of day/month/year, do the Sort and then swap back again: (* Example data *) datelist = DateString[# + AbsoluteTime[{2007, 01, 01}], {"Day", "/", "Month", "/", "Year"}] & /@ RandomInteger[10^8, 10] {"29/02/2008", "15/12/2007", "06/09/2007", "06/10/2008", "05/03/2007", "24/01/2010", ...


12

According to The Chicago Manual of Style, para. 18.57/18.58, punctation marks are ignored. 18.57 The letter-by-letter system. In the letter-by-letter system, alphabetizing continues up to the first parenthesis or comma; it then starts again after the punctuation point. Word spaces and all other punctuation marks are ignored. Both open and ...


11

I do not believe that this behaviour is a bug. The correct usage would be SortBy[#age&] or SortBy[Key@"age"]. The rest of this response will explain these assertions. The crucial point is that the "age" argument in SortBy["age"] is not conferred with any special meaning on account of SortBy being used as a Dataset operator. In the absence of such ...


10

Note: While this whole post is just playing, the idea for the solution comes from an answer to a very real problem I had, so it wasn't just a futile exercise. The key is that (in v8) a shared function (set with SetSharedFunction) is always evaluated on the main kernel. Thanks to Andrew Moylan for pointing this out! Here's my incredibly wasteful solution ...


10

As you said in your comment that you just want a well displayed formula, I suggest using Row to force specific orders. A rough example will look like following, you might want to adjust the priority level according to your needs: expr = A^2 e^2 SuperMinus[\[Phi]] SuperPlus[\[Phi]] + A e SuperMinus[\[Phi]] SuperPlus[\[Phi]] Subscript[c, 2 w] Subscript[g, ...


10

Something like this might be helpful. It replaces the unsorted list of symbols with a sorted list, lets Mathematica rearrange the expression in the normal way, and then applies a HoldForm before replacing the symbols back again. reorderSymbols[expr_, symbols_List] := With[{s = symbols}, HoldForm[Evaluate[expr /. Thread[s -> Sort@s]]] /. Thread[Sort@s ...


10

I share Leonid's reservations about basing the sort on simple string length. I would use a similar Ordering method, but I would parse things differently. Consider this test set: names = {"~/Hex_12.dat", "~/Hex_192.dat", "~/Oct_99.dat", "~/Hex_014.dat", "~/Hex_24_17.dat", "~/Hex_24_5.dat", "~/Hex_48.dat", "~/Hex_6.dat", "~/Hex_96.dat", ...


10

How about: list /. Thread[# -> Ordering@#] &@Union@list (* {3, 1, 1, 3, 2, 2, 3, 2} *) You can use the additional arguments of Ordering to sort it the other way: list /. Thread[# -> Ordering[#, All, Greater]] &@Union@list (* {1, 3, 3, 1, 2, 2, 1, 2} *)


10

Position is looking for an exact match (pseudo-SameQ), rather than a numeric one. You will get the result you want with: Position[data[[All, 1]], _?(# == xlow &)] Or: Position[data[[All, 1]], x_ /; x == xlow] Generally you should use Equal (short form ==) any time you are trying to mach Real numbers, to allow for small rounding errors. Using the ...


10

SeedRandom[42]; haystack = RandomReal[1, 6300]; AbsoluteTiming[ f = Nearest[haystack -> Range@Length@haystack]; {f[.3, 1], haystack[[f[.3, 1]]]}] (* -> {0.015625, {{3123}, {0.300033}}} *) Of course in this case most of the time is expended calculating the nearest function. If your points aren't changing from one use to the next, the time for ...


10

To sort by a specific element use a pure function with the number in question. For your case (the second element) just do: SortBy[a, #[[2]] &] {{7, 1, 4}, {1, 2, 3}, {12, 4, 8}, {3, 5, 6}, {10, 7, 1}} You can also use Sort like this: Sort[a, #1[[2]] < #2[[2]] &]


9

To get list b, you need Sort[]: Sort[{1, 4, 6, 7, 0, 2}, GreaterEqual]. To get list c, you need Ordering[]: Ordering[{1, 4, 6, 7, 0, 2}, All, GreaterEqual].



Only top voted, non community-wiki answers of a minimum length are eligible