Function Repository Resource:

RatioPartition

Source Notebook

Partition a list into sublists with lengths proportional to weights in another list

Contributed by: Daniel Robinson

ResourceFunction["RatioPartition"][list,{weight1,weight2, }]

splits list into sublists with lengths proportional to weight1,weight2, ….

Details and Options

ResourceFunction["RatioPartition"][list,{weight1,weight2,},"Randomize"True] randomizes list before splitting into sublists.
The weighti must all be positive real numbers.
Generated sublists always preserve the items in the original list. For this reason, precise partitions are not always possible.

Examples

Basic Examples (2) 

Partition a list into sublists containing 10%, 30% and 60% of the data:

In[1]:=
ResourceFunction["RatioPartition"][Range[10], {10, 30, 60}]
Out[1]=

Verify that there are no overlapping sublists:

In[2]:=
Flatten[%] == Range[10]
Out[2]=

Partition a list into sublists containing 22%, 27% and 51% of the data. This time, the partitions can only be approximated:

In[3]:=
ResourceFunction["RatioPartition"][Range[10], {22, 27, 51}]
Out[3]=

Scope (3) 

Partition a list into any number of parts:

In[4]:=
Manipulate[
 Grid[{{"n", "Sublists"}, Sequence @@ Thread[{Range[n], ResourceFunction["RatioPartition"][Range[20], RandomInteger[{1, Round[20/n]}, n]]}]}, Alignment -> {{Right, Left}}, BaseStyle -> "Text", Dividers -> {{2 -> LightGray}, {2 -> LightGray}}], {n, 1, 20, 1}]
Out[4]=

Partition a list using decimals or fractions:

In[5]:=
ResourceFunction["RatioPartition"][Range[13], {0.17, 1/2, 0.33}]
Out[5]=

Partition a list using weights that don’t sum to a power of 10:

In[6]:=
ResourceFunction["RatioPartition"][Range[10], {123, 4567, 8910}]
Out[6]=

Options (1) 

Randomize the data before partitioning with the "Randomize" option:

In[7]:=
ResourceFunction["RatioPartition"][Range[10], {10, 30, 60}, "Randomize" -> True]
Out[7]=

Applications (3) 

RatioPartition is useful for separating data for training neural nets. Partition some randomized data into 60% training data, 20% validation data and 20% testing data:

In[8]:=
{trainingData, validationData, testingData} = ResourceFunction["RatioPartition"][
   ResourceData["MNIST", "TrainingData"], {60, 20, 20}, "Randomize" -> True];

Train a classifier:

In[9]:=
cf = Classify[trainingData, ValidationSet -> validationData]
Out[9]=

Measure the accuracy of the classifier:

In[10]:=
ClassifierMeasurements[cf, testingData, "Accuracy"]
Out[10]=

Properties and Relations (3) 

When exact partitions are not possible, the order of the weights may affect the lengths of the resulting sublists:

In[11]:=
Length /@ ResourceFunction["RatioPartition"][Range[10], {1, 5, 5}]
Out[11]=
In[12]:=
Length /@ ResourceFunction["RatioPartition"][Range[10], {5, 1, 5}]
Out[12]=

The list of weights is scaled to the interval [0, 1]. Therefore, for best results, choose weights that add up to a power of 10. Not doing so may result in sublists of unexpected lengths:

In[13]:=
ResourceFunction["RatioPartition"][Range[10], {0.2, 0.3, 0.5}]
Out[13]=
In[14]:=
ResourceFunction["RatioPartition"][Range[10], {0.2, 0.3, 0.1}]
Out[14]=

Using a single weight will leave the list unchanged (albeit as a sublist):

In[15]:=
ResourceFunction["RatioPartition"][Range[10], {4}]
Out[15]=

Possible Issues (2) 

Due to rounding, it is possible to have empty lists in the output:

In[16]:=
ResourceFunction["RatioPartition"][Range[10], {100, 1}]
Out[16]=

Weights must be positive real numbers:

In[17]:=
ResourceFunction["RatioPartition"][Range[10], {a, -1}]
Out[17]=

Publisher

Daniel Robinson

Version History

  • 1.0.0 – 27 February 2020

Related Resources

Author Notes

Future improvements:

Make RatioPartition[list,n] equivalent to Partition[list,n] (while ensuring the "Randomize" option still works).

Make RatioPartition[n] equivalent to RandomPartition[n] (which needs Combinatorica`).

License Information