代码之家  ›  专栏  ›  技术社区  ›  Mr_and_Mrs_D

pandas使用多索引从距离矩阵创建数据帧

  •  0
  • Mr_and_Mrs_D  · 技术社区  · 6 年前

    我有两种对象——F和P——上面有标记,我想计算属于不同类别的每个标记之间的距离,然后构建一个数据帧,每个数据帧有一行来自不同类别的每对标记及其距离。下面的代码似乎可以满足我的要求:

    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)
    

    它打印:

    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
    

    distances_matrix . 我看了很多其他问题:

    1 回复  |  直到 6 年前
        1
  •  2
  •   BENY    6 年前

    这是你需要的吗?

    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