# How to shuffle just one column of table/list?

I have a list in form {{X1,Y1,type},....{Xn,Yn,type}}. X and Y are coordinates and type is a number between 1 to 15, the length of the list is 12000, so I can not upload the data here. I need to keep (X,Y) fixed and randomize (shuffle) the third column (type) to create another list. How can I do that? Also, How can I create many (over 100) different version of shuffled list?

• Tip: Even if you can not share the list with 12000 entries, you could still show the structure with made up content for N=3 or something, so we get a better idea what you're talking about. Commented Feb 9, 2022 at 9:58

data = Join[Array[x, {10, 2}], List /@ Array[z, {10}], 2];

MatrixForm @ data


You can use SubsetMap + RandomSample:

SeedRandom[1];
data2 = SubsetMap[RandomSample, {All, 3}] @ data;

MatrixForm @ data2


Alternatively, you can use in-place part assignment to replace the third column data:

SeedRandom[1];
data[[All, 3]] = RandomSample[data[[All, 3]]];

MatrixForm @ data


Update: "How can I create too many (over 100) different version of shuffled list?"

n = 5; (* use n = 100 in your case *)

SeedRandom[1];

datasets = Join[data[[All, ;; 2]], List /@ #, 2] & /@
Table[RandomSample[data[[All, 3]]], n];

MatrixForm /@ datasets


A variation using MapThread:

Create the subscript array of the required length and then use MapThread:

pts = Transpose@{Range[10], Range[10], RandomSample[Range[10]]}
MapThread[Part, {{x, y, z}, #}] & /@ pts


$$\left( \begin{array}{ccc} x[[1]] & y[[1]] & z[[9]] \\ x[[2]] & y[[2]] & z[[2]] \\ x[[3]] & y[[3]] & z[[7]] \\ x[[4]] & y[[4]] & z[[6]] \\ x[[5]] & y[[5]] & z[[4]] \\ x[[6]] & y[[6]] & z[[3]] \\ x[[7]] & y[[7]] & z[[10]] \\ x[[8]] & y[[8]] & z[[1]] \\ x[[9]] & y[[9]] & z[[5]] \\ x[[10]] & y[[10]] & z[[8]] \\ \end{array} \right)$$

which you can weave further into your solution using the excellent answer by @kglr.

Storing an array of random permuted data beforehand does not offer many advantages for computation, but it may be required for presentation purposes.

arr=Array[a, {10, 3}];

Join[arr[[All,1;;2]],Transpose[{RandomSample[arr[[All,3]]]}],2]//TeXForm


$$\left( \begin{array}{ccc} a(1,1) & a(1,2) & a(7,3) \\ a(2,1) & a(2,2) & a(2,3) \\ a(3,1) & a(3,2) & a(8,3) \\ a(4,1) & a(4,2) & a(9,3) \\ a(5,1) & a(5,2) & a(6,3) \\ a(6,1) & a(6,2) & a(1,3) \\ a(7,1) & a(7,2) & a(10,3) \\ a(8,1) & a(8,2) & a(3,3) \\ a(9,1) & a(9,2) & a(5,3) \\ a(10,1) & a(10,2) & a(4,3) \\ \end{array} \right)$$

SeedRandom[0];

x = Array[a, {5, 3}];


Using MapThread with Append

MapThread[Append, {x[[All, 1 ;; 2]], RandomSample @ x[[All, 3]]}] // MatrixForm


Using MapAt with double Transpose

MapAt[RandomSample, Transpose @ x, 3] // Transpose // MatrixForm


SeedRandom[0];

x = Array[a, {5, 3}];


Grabbing the @eldo's example, a variant using TakeList is the following:

Join @@@ Thread[MapAt[List /@ RandomSample[x[[All, 3]]] &,
Thread[TakeList[#, {2, 1}] & /@ x], {2}]] // TeXForm


$$\left( \begin{array}{ccc} a(1,1) & a(1,2) & a(4,3) \\ a(2,1) & a(2,2) & a(2,3) \\ a(3,1) & a(3,2) & a(5,3) \\ a(4,1) & a(4,2) & a(1,3) \\ a(5,1) & a(5,2) & a(3,3) \\ \end{array} \right)$$