Frequently in my profession I deal with large arrays of data. Typically these are mixed types including integers, strings, dates, and reals. To recreate a typical data array:
randstring := StringJoin@FromCharacterCode@RandomInteger[{97, 122}, RandomInteger[{5,20}]]
testdata = RandomInteger[{0, 100000}, {1200000, 10}];
testdata[[All, 10]] = Table[randstring, {1200000}];
testdata[[All, 5]] = testdata[[All, 5]] + RandomReal[];
ByteCount[testdata]/(1024.^2)
367.354
So, we'll assume column 1 contains a unique identifier for each list. It is desired to select all lists with a certain unique identifier and perform some kind of calculation on that. As an example we'll calculate the Quartiles of the data in the 5th column.
selquarts[id_] := With[{sel = Select[testdata, #[[1]] == id &]},
If[sel != {}, Quartiles[sel[[All, 5]]], {}]]
id = 5555;
selquarts[id] // Timing
{1.092007, {28123.4, 45390.9, 65606.4}}
So, ~1.1 seconds to select these items. We can speed it up with Cases
:
selquarts2[id_] := With[{sel = Cases[testdata, {id, __}]},
If[sel != {}, Quartiles[sel[[All, 5]]], {}]]
selquarts2[id] // Timing
{0.171601, {28123.4, 45390.9, 65606.4}}
Much better, but knowing there are roughly 100,000 unique ids, calculating this will take ~4.75 hours.
Here are the ways I've sped it up so far:
Create a "position lookup" vector:
ids = testdata[[All,1]];
selquarts3[id_] := With[{pos = Flatten@Position[ids, id]}, If[pos != {}, Quartiles[testdata[[pos, 5]]], {}]]
selquarts3[id] // Timing
{0.062400, {28123.4, 45390.9, 65606.4}}
Create a "conditioned dataset", however if your calculation depends on something other than the data in column 5, it becomes less practical.
conditioned = GatherBy[testdata, First];
conditioned = {#[[1, 1]], #[[All, 5]]} & /@ conditioned;
selquarts4[id_] := With[{sel = Cases[conditioned, {id, {__}}][[1, 2]]},
If[sel != {}, Quartiles[sel], {}]]
selquarts4[id] // Timing
{0.015600, {28123.4, 45390.9, 65606.4}}
So, a long worded question to simply ask are there better ways to do this? Maybe using Dataset
or Association
s? Emphasis is on speed more than memory usage.