1

I have a groupby object:

  col1 col2         x         y         z
0    A   D1  0.269002  0.131740  0.401020
1    B   D1  0.201159  0.072912  0.775171
2    D   D1  0.745292  0.725807  0.106000
3    F   D1  0.270844  0.214708  0.935534
4    C   D1  0.997799  0.503333  0.250536
5    E   D1  0.851880  0.921189  0.085515

How do I sort the groupby object into the following:

  col1 col2         x         y         z
0    A   D1  0.269002  0.131740  0.401020
1    B   D1  0.201159  0.072912  0.775171
4    C   D1  0.997799  0.503333  0.250536
2    D   D1  0.745292  0.725807  0.106000
5    E   D1  0.851880  0.921189  0.085515
3    F   D1  0.270844  0.214708  0.935534

And then compute the means between Row A {x, y, z} and Row B {x, y, z}, Row B {x, y, z} and Row C {x, y, z}... such that I have:

    col1 col2    x_mean    y_mean    z_mean
0    A-B   D1  0.235508  0.102326   0.58809
1    B-C   D1       ...       ...       ...
4    C-D   D1       ...       ...       ...
2    D-E   D1       ...       ...       ...
5    E-F   D1       ...       ...       ...
3    F-A   D1       ...       ...       ...

I am basically trying to computationally find the midpoints between vertices of a hexagonal structure (well... more like 10 million). Hints appreciated!

cs95
  • 379,657
  • 97
  • 704
  • 746
James
  • 274
  • 4
  • 12

1 Answers1

1

I believe you need groupby with rolling and aggregate mean, last for pairs use shift and delete first NaNs rows per group:

print (df)
 col1 col2         x         y         z
0    A   D1  0.269002  0.131740  0.401020
1    B   D1  0.201159  0.072912  0.775171
2    D   D1  0.745292  0.725807  0.106000
3    F   D2  0.270844  0.214708  0.935534 <-change D1 to D2
4    C   D2  0.997799  0.503333  0.250536 <-change D1 to D2
5    E   D2  0.851880  0.921189  0.085515 <-change D1 to D2
#
df = (df.sort_values(['col1','col2'])
        .set_index('col1')
        .groupby('col2')['x','y','z']
        .rolling(2)
        .mean()
        .reset_index())
df['col1'] = df.groupby('col2')['col1'].shift() + '-' + df['col1']
df = df.dropna(subset=['col1','x','y','z'], how='all')
#alternative
#df = df[df['col2'].duplicated()]
print (df)

  col2 col1         x         y         z
1   D1  A-B  0.235081  0.102326  0.588095
2   D1  B-D  0.473226  0.399359  0.440586
4   D2  C-E  0.924840  0.712261  0.168026
5   D2  E-F  0.561362  0.567948  0.510524
jezrael
  • 822,522
  • 95
  • 1,334
  • 1,252