Учитывая такой фрейм данных Pandas:

|------|-------|
|col1  |col2   |
|------|-------|
|a1    |abc    |
|a2    |bcd    |
|a3    |kfs    |
|------|-------|

Есть ли функция для эффективного (фактический DataFrame имеет> 10.000 строк) создать матрицу, как показано ниже, с использованием пользовательской функции для определения значений числовых полей?

|------|-------|------|-------|
|      |a1     |a2    |a3     |
|------|-------|------|-------|
|a1    |1.000  |0.362 |0.643  |
|a2    |0.362  |1.000 |0.364  |
|a3    |0.643  |0.364 |1.000  |
|------|-------|------|-------|

Что я пробовал до сих пор:

  • Преобразование DataFrame в список и использование вложенного списка. Однако это занимает слишком много времени с точки зрения производительности.
  • Использование sklearn pairwise_distance с моей пользовательской функцией, определенной как метрика. Здесь та же проблема с производительностью.

В конечном итоге будет сгенерировано следующее представление:

|------|--------------------------------------|
|a1    |{a1: 1.000}, {a2: 0.362}, {a3: 0.643} |
|a2    |{a1: 0.362}, {a2: 1.000}, {a3: 0.364} |
|a3    |{a1: 0.643}, {a2: 0.364}, {a3: 1.000} |
|------|--------------------------------------|
-1
Sebastian Hätälä 30 Июн 2020 в 01:14

1 ответ

Лучший ответ

Один из способов сделать это - создать перекрестное произведение между всеми возможными значениями col1, выполнить вычисление для каждой пары, а затем выполнить поворот:

# dummy data
df = pd.DataFrame({
    "col1": [f"a_{i}" for i in range(5)], 
    "col2": range(5)})

# the following dataframe is produced. We're now looking for a way to 
# run some calculation for each combination of col1 x col1
  col1  col2
0  a_0     0
1  a_1     1
2  a_2     2
3  a_3     3
4  a_4     4

df = pd.merge(df.assign(dummy=1), df.assign(dummy=1), on = "dummy").drop("dummy", axis=1)
df["res"] = df.col2_x * df.col2_y
pd.pivot_table(df, index="col1_x", columns="col1_y", values = "res")

Результат:

col1_y  a_0  a_1  a_2  a_3  a_4
col1_x                         
a_0       0    0    0    0    0
a_1       0    1    2    3    4
a_2       0    2    4    6    8
a_3       0    3    6    9   12
a_4       0    4    8   12   16
1
Roy2012 30 Июн 2020 в 06:35