0
$\begingroup$

Consider a list:

ZXV = {{z1, x1, v1}, {z2, x2, v2},........................} 

where $z$ is Z co-ordinate, $x$ is X co-ordinate, $v$ is the value at the point $i$.

I want to create a grid based on squares 100 units wide. I then want to calculate the average value within the grid.

I then want to create a list of averages, with the centre point of each square - {{cz1, cx1, av1}, {cz2, cx2, av2}, .......} where $cz$ is centre for $z$, $cx$ is centre for $x$, and $av$ is average value for the square unit.

I was looking at something like

Split[mylist, Chop[#2 - #1 - 1] == 0 &]

but I need to setup recursive loop [2#-#1], [#3- #1], [#4 - #1] until the rule [#Number - #1] > 100 is reached

How could I accomplish this?

$\endgroup$
3
$\begingroup$
mylist = Transpose[{RandomReal[100, 1000], RandomReal[100, 1000], RandomReal[1, 1000]}];

binned = GatherBy[#, Floor[#[[2]]] &] & /@ GatherBy[mylist, Floor[#[[1]]] &];

means = Join @@ Map[Mean, binned, {2}];

BubbleChart[Tooltip /@ means, GridLines -> {Range@100, Range@100}, 
            BubbleSizes -> {0.005, .005}]

Mathematica graphics

$\endgroup$
  • $\begingroup$ Thks - very useful. Here is a sample of the data. Pls can you apply. list = {{5.16262, 11.872, -1.2275}, {5.16262, 12.64, -1.1461}, {5.16262, 12.672, -1.1435}, {5.16262, 12.8, -1.1372}, {5.16262, 12.832, -1.1356}, {5.16262, 12.864, -1.1388}, {5.16262, 12.896, -1.1416}, {5.16262, 12.928, -1.139}, {5.16262, 12.96, -1.1374}, {5.16262, 12.992, -1.1372}, {5.16262, 13.024, -1.1341}, {5.16262, 13.056, -1.129}, {5.16262, 13.088, -1.1346}, {5.16262, 13.12, -1.1337}, {5.16262, 13.152, -1.1323}, {5.16262, 13.184, -1.133}, {5.16262, 13.216, -1.1358}, {5.16262, 13.248, -1.1383}} $\endgroup$ – SPIL Apr 22 '16 at 7:19
2
$\begingroup$

I think you can use Partition to form the group of four points, and then calculate the mean value in each group.

For example here are some data on a 100 by 100 grids

data = N@Table[Cos[x^2 + y^2], {x, π/100, π, π/100}, {y, π/100, π, π/100}];

To form a group of four point

data1 = Partition[data, {2, 2}, 1];

then the mean value is

data2= Map[Mean[Mean[#]] &, data1, {2}];

If your data has the form of {{x1,y1,z1},..} shape, then you can apply this to each dimension

dataXYZ = 
 N@Table[{x, y, Cos[x^2 + y^2]}, {x, π/100, π, π/100}, {y, π/100, π, π/100}];

Transpose[Map[Mean[Mean[#]] &, Partition[#, {2, 2}, 1], {2}] & /@ 
  Transpose[dataXYZ, {2, 3, 1}], {3, 1, 2}]

Here is an example shows what it does, where the black dots are the original grid and the red dots are the center of each square.

grid1 = Table[{i, j}, {i, 10}, {j, 10}];
grid2 = Transpose[Map[Mean[Mean[#]] &, Partition[#, {2, 2}, 1], {2}] & /@ 
   Transpose[grid1, {2, 3, 1}], {3, 1, 2}]
Graphics[{PointSize[Large], Point[Flatten[grid1, 1]], Red, 
  Point[Flatten[grid2, 1]]}]

enter image description here

$\endgroup$
  • $\begingroup$ Thks - very useful. Here is a sample of the data. Pls can you apply. list = {{5.16262, 11.872, -1.2275}, {5.16262, 12.64, -1.1461}, {5.16262, 12.672, -1.1435}, {5.16262, 12.8, -1.1372}, {5.16262, 12.832, -1.1356}, {5.16262, 12.864, -1.1388}, {5.16262, 12.896, -1.1416}, {5.16262, 12.928, -1.139}, {5.16262, 12.96, -1.1374}, {5.16262, 12.992, -1.1372}, {5.16262, 13.024, -1.1341}, {5.16262, 13.056, -1.129}, {5.16262, 13.088, -1.1346}, {5.16262, 13.12, -1.1337}, {5.16262, 13.152, -1.1323}, {5.16262, 13.184, -1.133}, {5.16262, 13.216, -1.1358}, {5.16262, 13.248, -1.1383}} $\endgroup$ – SPIL Apr 22 '16 at 7:18
2
$\begingroup$

Let's say you have this data, just using a random set here for completeness,

SeedRandom[55];
(* A set of random 2D coordinates *)
list = RandomReal[100, {1000, 2}];
(* attach a set of less-random values as the third coordinate *)

list = {#1, #2, #1 + #2 + RandomReal[{-50, 50}]} & @@@ list;

You can view the data using a ListDensityPlot or ListPlot,

ListDensityPlot[list, ColorFunction -> "Rainbow"]
ListPlot[Style[{#1, #2}, ColorData["Rainbow"][#3/100]] & @@@ list, 
 AspectRatio -> 1, 
 GridLines -> {Range[0, 100, 20], Range[0, 100, 20]}]

enter image description here

You can see that the values generally get larger as x and z get larger, but that density plot is horrible.

To get a list of the values in a particular rectangular region, use Select:

Last/@Select[list, 0 <= #[[1]] <= 20 && 0 <= #[[2]] <= 20 &]

(*  {37.5551, 1.32275, 16.2364, 66.5277, 18.6801,......, 15.8541, 25.897, 33.8019, 19.1619} *)

And you can just use Mean to get the mean value in that region (or Total to get the total value).

Use Table to collect all the mean values over, for example, a 5 by 5 grid,

{dx, dz} = {20, 20};
gridmean = Table[
   Mean[
    Last /@ 
     Select[list, x <= #[[1]] <= x + dx && z <= #[[2]] <= z + dz &]
    ]
   , {x, 0, 80, dx}, {z, 0, 80, dz}];

And then use ListDenistyPlot to show the mean values,

ListDensityPlot[gridmean, ColorFunction -> "Rainbow", 
 InterpolationOrder -> 0, DataRange -> {{0, 100}, {0, 100}}]

enter image description here

Alternatively, you could create a list of Rectangle objects and use RegionMember to select the points,

regions = 
  Table[Rectangle[{x, z}, {x + dx, z + dz}], {x, 0, 80, dx}, {z, 0, 
    80, dz}];
gridmean = Table[
  Mean[
   Last /@ Select[list, RegionMember[regions[[n, m]], #[[;; 2]]] &]
   ], {n, 5}, {m, 5}]

But this is a bit slower

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.