Как сделать саморазностную симметричную матрицу, используя в pandas, используя массив?

#python #numpy

#python #numpy

Вопрос:

У меня есть ряд значений. Теперь я хочу иметь симметричную матрицу с этой серией. Пересечение ячейки должно быть разницей.

Например, ряд называется means, и он выглядит так:

 {'Q2.1_1': 2014.764423076923,
 'Q2.1_2': 2015.7421052631578,
 'Q2.1_3': 2016.4635416666667,
 'Q2.1_4': 2015.4532019704434,
 'Q2.1_5': 2014.2727272727273,
 'Q2.1_6': 2016.320512820513,
 'Q2.1_7': 2013.525,
 'Q2.1_8': 2015.0,
 'Q2.1_9': 2015.632183908046,
 'Q2.1_10': 2013.0096618357488,
 'Q4.1_1': 2014.7339901477833,
 'Q4.1_2': 2013.1581920903955,
 'Q4.1_3': 2013.7711864406779,
 'Q4.1_4': 2013.387640449438,
 'Q4.1_5': 2015.2732919254659,
 'Q4.1_6': 2014.764705882353,
 'Q4.1_7': 2014.91452991453,
 'Q4.1_8': 2013.7643678160919,
 'Q4.1_9': 2014.4528301886792,
 'Q4.1_10': 2016.2547770700637,
 'Q4.1_11': 2011.8423913043478,
 'Q4.1_12': 2013.202380952381,
 'Q4.1_13': 2012.1944444444443,
 'Q6.1_1': 2016.6825396825398,
 'Q6.1_2': 2014.7605633802816,
 'Q8.1_1': 2013.4792899408285,
 'Q8.1_2': 2012.6614583333333,
 'Q8.1_3': 2015.4470588235295,
 'Q8.1_4': 2013.2890625,
 'Q8.1_5': 2013.8778625954199,
 'Q10.1_1': 2013.503816793893,
 'Q10.1_2': 2014.125654450262,
 'Q10.1_3': 2014.4702702702702,
 'Q12.1_1': 2011.2634146341463}
 

Новая матрица должна быть такой:
Corss_tab

После этой команды,

 pd.crosstab(index=means.index, columns=means.index, values=means.values, aggfunc=np.mean)
 

Я могу создать правильный индекс и столбцы. Но я понятия не имею, как правильно получить значения каждой ячейки.

Комментарии:

1. Что 'Q4.1_2' означает с точки зрения матрицы, которую вы ожидаете? строка 4, столбец 2?

2. Просто уникальный идентификатор, не имеющий ничего общего с номером строки или индекса.

3. Нет, тогда я в замешательстве, 'Q4.1_4': 2013.387640449438 где это значение вписывается в матрицу?

4. Итак, если строка ‘Q4.1._1’, а столбец ‘Q4.1_4’, значение в матрице будет 2014.733-2013.387…

5. Проверьте мой ответ, это то, что вы ищете?

Ответ №1:

Давайте попробуем использовать NumPy с broadcasting

(Я назвал словарь, который вы указали в своем вопросе, как means )

 values = np.array(list(means.values()))[:,None]
keys = list(means.keys())

print(pd.DataFrame(np.abs(values - values.T), columns=keys, index=keys))
 
            Q2.1_1    Q2.1_2    Q2.1_3    Q2.1_4    Q2.1_5    Q2.1_6    Q2.1_7  
Q2.1_1   0.000000  0.977682  1.699119  0.688779  0.491696  1.556090  1.239423   
Q2.1_2   0.977682  0.000000  0.721436  0.288903  1.469378  0.578408  2.217105   
Q2.1_3   1.699119  0.721436  0.000000  1.010340  2.190814  0.143029  2.938542   
Q2.1_4   0.688779  0.288903  1.010340  0.000000  1.180475  0.867311  1.928202   
Q2.1_5   0.491696  1.469378  2.190814  1.180475  0.000000  2.047786  0.747727   
Q2.1_6   1.556090  0.578408  0.143029  0.867311  2.047786  0.000000  2.795513   
Q2.1_7   1.239423  2.217105  2.938542  1.928202  0.747727  2.795513  0.000000   
Q2.1_8   0.235577  0.742105  1.463542  0.453202  0.727273  1.320513  1.475000   
Q2.1_9   0.867761  0.109921  0.831358  0.178982  1.359457  0.688329  2.107184   
Q2.1_10  1.754761  2.732443  3.453880  2.443540  1.263065  3.310851  0.515338   
Q4.1_1   0.030433  1.008115  1.729552  0.719212  0.461263  1.586523  1.208990 
...
 

Комментарии:

1. Фантастика. Я не понимал, что могу использовать numpy для этого. Спасибо!

2. Вы упомянули numpy в качестве тега для вопроса, поэтому я предложил это в качестве решения 🙂

3. Не могли бы вы рассказать мне больше о последней части преобразования значений? Что здесь делает [:,None] ?

4. Итак, [:, None] в основном измените массив (34,) shape 1D (34,1) на массив shape 2D, добавив новое измерение. Когда вы вычитаете values-values.T , вы вычитаете (34,1) - (1,34) , что возвращает (34,34) 2D-матрицу благодаря numpy broadcasting. Это также известно как внешняя разница.

5. Вы можете прочитать больше о том, как это работает здесь . Дайте мне знать, если это поможет, спасибо!