3
$\begingroup$

I'm trying to do interpolation on a large list of data of the format {{x1, y1}, {x2, y2}, {x3, y3}, ..., {xn, yn}} that is exported from a simulation.

Unfortunately, the exported data has some points {x_(i), y_(i)} and {x_(i + 1), y_(i + 1)} that share the same x point: x_(i) = x_(i + 1). This is just because of poor precision in the export process from the simulation.

The interpolation function doesn't like the fact that there are duplicate points that share the same x value, and gives me an error message with no output interpolation.

I want to take the duplicate points {x_(i), y_(i)} and {x_(i + 1), y_(i + 1)}, average y_(i) and y_(i + 1) and remove x_(i + 1) from the list. The final list should have no duplicates.

It should be pretty straightforward. I'm just a little slow at programming, because I don't have to do it very often.

$\endgroup$
  • $\begingroup$ Thanks guys! Both of these seem to work, and are more elegant than what I could have come up with. $\endgroup$ – LooseyGoose Feb 14 '19 at 20:34
4
$\begingroup$

When the x-values are exact duplicates, the following might work (data is the n x 2 -matrix with the data points).

KeySort@GroupBy[data, First -> Last, Mean]

This produces an association. You may obtain a list again with

Transpose[ 
 Through[{Keys, Values}[
  KeySort@GroupBy[data, First -> Last, Mean]]
  ]
 ]
|improve this answer|||||
$\endgroup$
  • 1
    $\begingroup$ Or go straight to the list with data2 = {#[[1, 1]], Mean[#[[All, 2]]]} & /@ GatherBy[data, First] $\endgroup$ – Bob Hanlon Feb 14 '19 at 21:01
1
$\begingroup$
data = {{1, 2}, {3, 4}, {5, 6}, {1, 6}};

assocs = AssociationThread @* Apply[Rule] /@ data

<|1 -> 2|>, <|3 -> 4|>, <|5 -> 6|>, <|1 -> 6|>}

means = Merge[Mean][assocs]

<|1 -> 4, 3 -> 4, 5 -> 6|>

List @@@ Normal @ means

{{1, 4}, {3, 4}, {5, 6}}

|improve this answer|||||
$\endgroup$
0
$\begingroup$

How about this?

data = {{1, 2}, {3, 4}, {5, 6}, {1, 2}};

data2 = Union[data, SameTest -> (#1[[1]] == #2[[1]] &)]

(* {{1,2},{3,4},{5,6}} *)

If the x values are not exact duplicates then you can use:

SameTest -> (Abs[#1[[1]] - #2[[1]]] < minDifference &)

with minDifference set to an appropriate value.

|improve this answer|||||
$\endgroup$
  • $\begingroup$ My answer does not in fact average the y values. I voted for Henrick’s answer! $\endgroup$ – David Keith Feb 14 '19 at 21:52

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.