GatherBy[data, Floor[First[#]/10]&] is close, but it leaves out empty bins.

BinLists[data[[All, 1]], 10] is also similar, but it only returns the list of ages, I can't get it to include the names as well.

Ideally, I'd like to have a function with similar syntax and performance to BinLists, i.e.: binListsBy[data, {10,70,10}, First]. And the function should be fast, because I'm going to use it on millions of entries (pixels of an image, in fact).

(Following Mr.Wizard's meta discussion, I'm not going to add "what have I tried" in my question - I'm really looking for better ideas, or maybe even a built-in function I haven't noticed. Instead I'll post my attempts as an answer.)

@Simon It very well could be, though in my memory it is/was a little different. Thanks for finding that. There are probably several questions like this around.
–
Mr.Wizard♦Jun 11 '14 at 12:07

(19357) is also related; despite my having the Accepted answer there jVincent posted the better method, which used priming of Tally much as my answer here does with GatherBy.
–
Mr.Wizard♦Jun 11 '14 at 12:12

2

What kind of input data will you use it on precisely? Specifically: what opportunities are there to use packed arrays?
–
SzabolcsJun 11 '14 at 13:01

I'm not particularly happy that I had to reinvent the "bin specification" logic that has to be somewhere in MMA (Histogram, BinCounts, BinLists all share the same logic). Also, the range/index replacement rules logic seems unnecessarily complex for such a simple task, but I couldn't come up with something simpler.

Are you going to add my functions to your timings?
–
Mr.Wizard♦Jun 16 '14 at 2:02

@Mr.Wizard: I'm trying to, but I honestly don't understand it well enough. To compare the timings, the function should take a function parameter, like the other versions. Yours (I think?) always gathers by the first subelement, which may or may not be faster than calling a user-supplied function.
–
nikieJun 16 '14 at 6:21

The OP's example does not sort the values in the output lists; that may not be desired.
–
Mr.Wizard♦Jun 11 '14 at 13:54

@Mr.Wizard this may or may not be done (see my update)
–
eldoJun 11 '14 at 14:04

Why not simply use this?: result = GatherBy[Join[Transpose[{Range[0, 100, 10], Table[" ", {11}]}], data], Floor[First[#]/10] &]; That is essentially what I did in my answer (fn).
–
Mr.Wizard♦Jun 11 '14 at 14:17

@Mr.Wizard - I didn't pretend to give a "better" answer but just wanted to know how I would write this myself. If you consider my answer as a duplicate of yours, please let me know and I delete it.
–
eldoJun 11 '14 at 14:37

No, I didn't meant to imply that, and please do not think you are not welcome to post an answer unless you claim it is "better." Rather I was trying to guide or refine the answer you gave. I like the visual presentation but I didn't vote for the answer because I'm not sure it's helpful to the OP. Anyway, my apologies for stepping on your toes.
–
Mr.Wizard♦Jun 11 '14 at 15:09

Mathematica is a registered trademark of Wolfram Research, Inc. While the mark is used herein with the limited permission of Wolfram Research, Stack Exchange and this site disclaim all affiliation therewith.