I have multiple time-steps of {x,y,z}coordinates data for some atoms. I would like to cluster the data for each frame and later identify how cluster compositions change and how each atom changes from one cluster to another.
That is, if atom number 54 was in cluster 1, how many members are lost or added in the next frame? Similarly, how do the number of clusters change and on average, what is the difference in cluster composition between one frame and the next? I am at a complete loss on how to proceed. Additionally, plotting the points in different clusters is also desirable. I have tried to create some data to demonstrate the problem.
The interpretation would be 10 frames of data and each frame has coordinates of 100 atoms. Each atom is identified by an atom number and each frame has a key of "frame number".
dataFrames = Association[Table[i -> Association[Table[i -> RandomReal[3, 3], {i, 1, 100}]], {i, 1, 10}]];
clustersEachFrame = FindClusters[#, Method -> "DBSCAN"] & /@ dataFrames;
A truncated output of clustersEachFrame is shown below
<|1 -> {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
18, 19, 20, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 63, 65, 66, 67, 68,
69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
85, 86, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100}, {22,
62, 64, 87}}, 2 -> {{1, 2, 3, 4, 5, 7, 9, 10, 11, 12, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 32, 34, 35, 37, 39, 40,
41, 42, 44, 45, 46, 47, 48, 49, 51, 52, 53, 55, 56, 58, 59, 60,
62, 63, 64, 65, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
79, 80, 81, 82, 85, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 98,
100}, {6, 33, 61, 84, 99}, {8, 13, 31, 38, 43, 50, 54, 66, 86,
97}, {36, 57, 83}},
Finding the total number of clusters in each frame is easy.
Length/@clustersEachFrame
<|1 -> 2, 2 -> 4, 3 -> 3, 4 -> 1, 5 -> 2, 6 -> 2, 7 -> 6, 8 -> 9,9 -> 3, 10 -> 3|>
Now, figuring out which cluster did a particular atom belong to in each frame? I have no idea how to do that. I look for any advice that the community can offer. Are there better data representations, eg. Dataset that I should think about for this or any connected advice is highly appreciated.
Thank you,
dataFrames = RandomReal[{-1, 1}, {10, 100, 3}]
an thenclustersEachFrame = FindClusters[#, Method -> "DBSCAN"] & /@ dataFrames
I'd try computing the center of mass for each cluster, then update the centers of mass of each with aNearest[com->"Index"]
--thus tracking the correspondence. Perhaps your "real data" might test this? $\endgroup$