У меня есть матрица расстояний, хранящаяся в виде кадра данных pandas df, который содержит расстояния между 400 парами координат в километрах следующим образом: 0 1 2 3 4 ...

1
Macter 5 Апр 2021 в 23:44

2 ответа

Лучший ответ

Вы можете использовать concat и ту же идею, что и для min, но с idxmin.

m = df>0
res = pd.concat([df[m].min(axis=1), df[m].idxmin(axis=1)], 
                axis=1, keys=['nearest_dist','nearest_id'])

print(res)
   nearest_dist nearest_id
0      1.698938          4
1      1.261969          4
2      0.420828          3
3      0.420828          2
4      0.812797          2

Или даже проще с agg

res = (df[m].agg(['min', 'idxmin'], axis=1)
            .rename(columns={'min':'nearest_dist', 'idxmin':'nearest_id'}))
3
Ben.T 5 Апр 2021 в 20:56

stack, затем groupby + idxmin, чтобы разрезать Серию.

s = df.rename_axis(columns='nearest_id').stack().loc[lambda x: x > 0]
s = (s.loc[s.groupby(level=0).idxmin()]
      .to_frame('nearest_dist')
      .reset_index(-1))

  nearest_id  nearest_dist
0          4      1.698938
1          4      1.261969
2          3      0.420828
3          2      0.420828
4          2      0.812797

Также можно построить DataFrame из numpy.

arr = df.where(df > 0).to_numpy()

pd.DataFrame({'nearest_id': np.nanargmin(arr, 1), 
              'nearest_dist': np.nanmin(arr, 1)},
             index=df.index)
3
ALollz 5 Апр 2021 в 21:06