1. Hay un marco de datos:

    data = pd.DataFrame({'o':[1,1,2,1,2],
                     'd':[1,2,1,3,3],
                     'distance':[3,5,10,6,8]})
    
  2. Quiero promediar la tercera columna cuando los índices de las dos primeras columnas son iguales o están invertidos. Por ejemplo, si o = 1, d = 2, distance = 5 o o = 2, d = 1, distance = 10, hay o = 1, d = 2, distance = 7.5 o o = 2, d = 1, distance = 7.5.

  3. A continuación, de acuerdo con este marco de datos de tres columnas, quiero generar una matriz simétrica, donde o y d es índice y columna, y el valor es distance. Además, la diagonal de la matriz se establece en 0.

  4. El resultado ideal es:

    a = np.array([[0,7.5,6],
            [7.5,0,8],
            [6,8,0]])
    
0
xc-2021 5 oct. 2021 a las 06:57

2 respuestas

La mejor respuesta
import pandas as pd
import numpy as np

data = pd.DataFrame({'o':[1,1,2,1,2],
                 'd':[1,2,1,3,3],
                 'distance':[3,5,10,6,8]})

data['query'] = data.apply(lambda row: tuple(sorted([row.o, row.d])), axis=1)  # ignore order

avg = data.groupby('query').distance.mean()

N = max(data.o.max(), data.d.max())  # square matrix
result = np.zeros((N, N), dtype=np.float32)

for (row, col), v in avg.items():
    row, col = row - 1, col -1  # index start from 0
    if row == col: continue  # diagonal set to 0
    result[row][col] = result[col][row] = v  # symmetric

print(result)
1
Adam 5 oct. 2021 a las 04:44

Uso:

#assigned sorted values to columns back
data[['o','d']] = np.sort(data[['o','d']], axis=1)

#pivoting with aggregate mean
df = data.pivot_table(index='o',columns='d', values='distance', aggfunc='mean')

#create matrix
df = df.combine_first(df.T)

#set 0 to diagonal
np.fill_diagonal(df.to_numpy(), 0)

print (df)
     1    2    3
1  0.0  7.5  6.0
2  7.5  0.0  8.0
3  6.0  8.0  0.0
0
jezrael 5 oct. 2021 a las 05:45