compute the difference of all possible rows
<p>Based on a selection <code>ds</code> of a dataframe <code>d</code> with:</p>

<p><code>{ 'x': d.x, 'y': d.y, 'a':d.a, 'b':d.b, 'c':d.c 'row:d.n'})</code> </p>

<p>Having <code>n</code> rows, <code>x</code> ranges from <code>0</code> to <code>n-1</code>. The column <code>n</code> is needed since it's a selection and indices need to be kept for a later query.</p>

<p>How do you efficiently compute the difference between each row (e.g.<code>a_0, a_1, etc</code>) of each column (<code>a, b, c</code>) without losing the rows information (e.g. new column with the indices of the rows that were used) ?</p>

<p><strong>MWE</strong> </p>

<p>Sample selection <code>ds</code>:</p>

<pre><code>             x           y      a     b      c     n

    554.607085  400.971878   9789  4151   6837   146
    512.231450  405.469524   8796  3811   6596   225
    570.427284  694.369140   1608  2019   2097   291
</code></pre>

<p>Desired output:</p>

<p><code>dist</code> euclidean distance <code>math.hypot(x2 - x1, y2 - y1)</code></p>

<p><code>da, db, dc</code> for <code>da: np.abs(a1-a2)</code> </p>

<p><code>ns</code> a string with both <code>n</code>s of the employed rows</p>

<p>the result would look like:</p>

<pre><code>             dist          da        db       dc         ns
42.61365102824963         993       340      241    146-225
293.82347069813255       8181      2132     4740    146-291
                ..         ..        ..       ..    225-291
</code></pre>

<p>You can use <code>itertools.combinations()</code> to generate the pairs:</p>

<p>Read data first:</p>

<pre><code>import pandas as pd
from io import StringIO
import numpy as np

text = """             x           y      a     b      c     n
    554.607085  400.971878   9789  4151   6837   146
    512.231450  405.469524   8796  3811   6596   225
    570.427284  694.369140   1608  2019   2097   291"""

df = pd.read_csv(StringIO(text), delim_whitespace=True)
</code></pre>

<p>Create the index and calculate the results:</p>

<pre><code>from itertools import combinations

index = np.array(list(combinations(range(df.shape[0]), 2)))

df1, df2 = [df.iloc[idx].reset_index(drop=True) for idx in index.T]

res = pd.concat([
    np.hypot(df1.x - df2.x, df1.y - df2.y),
    df1[["a", "b", "c"]] - df2[["a", "b", "c"]],
    df1.n.astype(str) + "-" + df2.n.astype(str)
], axis=1)

res.columns = ["dist", "da", "db", "dc", "ns"]
res
</code></pre>

<p>the output:</p>

<pre><code>         dist    da    db    dc       ns
0   42.613651   993   340   241  146-225
1  293.823471  8181  2132  4740  146-291
2  294.702805  7188  1792  4499  225-291
</code></pre>

python pandas