简体   繁体   English

熊猫从具有多索引的距离矩阵创建数据框

[英]Pandas create dataframe from distance matrix with multiindex

I have two kinds of objects - F and P - with tags on them and I want to calculate the distances between each tag that belongs to different category and then construct a dataframe with one row per pair of tags from different categories and their distance. 我有两种对象-F和P-上面有标签,我想计算属于不同类别的每个标签之间的距离,然后构造一个数据帧,每对来自不同类别的标签对及其距离分别具有一行。 The code below seems to do what I want: 下面的代码似乎可以满足我的要求:

import itertools
import operator
from collections import OrderedDict

import numpy as np
import pandas as pd
from scipy.spatial.distance import cdist

i = np.sqrt(2)
j = 2 * i
# dicts mapping category and tag to x, y coordinates
timeframe_f = OrderedDict(
    [(('F1', 'tag1f1'), (0, 0)), (('F2', 'tag1f2'), (-i, -i)), ])
timeframe_p = OrderedDict(
    [(('B1', 'tag1b1'), (i, i)), (('B2', 'tag1b2'), (j, j)),
     (('B2', 'tag2b2'), (2 * j, 2 * j)), ])
# calculate the distances
distances = cdist(np.array(list(timeframe_f.values())),
                  np.array(list(timeframe_p.values())), 'sqeuclidean')
print('distances:\n', distances, '\n')
# here is the matrix with the MultiIndex
distances_matrix = pd.DataFrame(data=distances,
                                index=pd.MultiIndex.from_tuples(
                                    timeframe_f.keys(),
                                    names=['F', 'Ftags']),
                                columns=pd.MultiIndex.from_tuples(
                                    timeframe_p.keys(),
                                    names=['P', 'Ptags']), )
print('distances_matrix:\n', distances_matrix, '\n')
# hacky construction of the data frame
index = list(map(lambda x: operator.add(*x), (
    itertools.product(timeframe_f.keys(), timeframe_p.keys()))))
# print(index)
multi_index = pd.MultiIndex.from_tuples(index)
distances_df = pd.DataFrame(data=distances.ravel(),
                            index=multi_index, ).reset_index()
print('distances_df:\n', distances_df)

It prints: 它打印:

distances:
 [[  4.  16.  64.]
 [ 16.  36. 100.]] 

distances_matrix:
 P             B1     B2       
Ptags     tag1b1 tag1b2 tag2b2
F  Ftags                      
F1 tag1f1    4.0   16.0   64.0
F2 tag1f2   16.0   36.0  100.0 

distances_df:
   level_0 level_1 level_2 level_3      0
0      F1  tag1f1      B1  tag1b1    4.0
1      F1  tag1f1      B2  tag1b2   16.0
2      F1  tag1f1      B2  tag2b2   64.0
3      F2  tag1f2      B1  tag1b1   16.0
4      F2  tag1f2      B2  tag1b2   36.0
5      F2  tag1f2      B2  tag2b2  100.0

but I would like to find a way to do this directly using the distances_matrix . 但我想找到一种直接使用distances_matrix做到这一点的方法。 I had a look at various other questions as: 我查看了其他各种问题,例如:

Is this what you need ? 这是您需要的吗?

distances_matrix.reset_index().melt(id_vars=['F','Ftags'])
Out[434]: 
    F   Ftags   P   Ptags  value
0  F1  tag1f1  B1  tag1b1    4.0
1  F2  tag1f2  B1  tag1b1   16.0
2  F1  tag1f1  B2  tag1b2   16.0
3  F2  tag1f2  B2  tag1b2   36.0
4  F1  tag1f1  B2  tag2b2   64.0
5  F2  tag1f2  B2  tag2b2  100.0

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM