使用所有可能的行对评估函数

时间:2019-07-10 20:42:05

标签: python pandas

我在Python 3中使用熊猫创建了一个数据框。在4组不同的条件(L1,L2,L3,L4)下进行了多次测量,每一行都是特定的测量,其中包含事件发生前后照片中像素亮度的分布参数。这是我为讨论而发明的示例:

Data = {'Picture_Type' : ['L1','L1','L1','L2','L2','L2','L3','L3','L3',
                          'L4','L4','L4'],
        'Before Mean' : [9,10,11,14,16,18,26,29,32,37,40,43],
        'Before StdDev' : [1,1.1,1.2,0.7,0.8,0.9,2.1,2.3,2.5,1.5,1.6,1.7],
        'After Mean' : [6,7,8,11,12,13,19,21,23,27,30,33],
        'After StdDev' : [0.7,0.8,0.9,1.3,1.5,1.7,2.5,2.7,2.9,1.5,1.6,1.7]}
df = DataFrame(Data)
print(df)

   Picture_Type  Before Mean  Before StdDev  After Mean  After StdDev
0            L1            9            1.0           6           0.7
1            L1           10            1.1           7           0.8
2            L1           11            1.2           8           0.9
3            L2           14            0.7          11           1.3
4            L2           16            0.8          12           1.5
5            L2           18            0.9          13           1.7
6            L3           26            2.1          19           2.5
7            L3           29            2.3          21           2.7
8            L3           32            2.5          23           2.9
9            L4           37            1.5          27           1.5
10           L4           40            1.6          30           1.6
11           L4           43            1.7          33           1.7

我需要评估一个需要所有可能的行配对输入的函数,并且我想按“ Picture_Type”汇总这些计算,以便得到这样的网格:

     L1    L2    L3    L4
L1    *     *     *     *
L2    *     *     *     *   
L3    *     *     *     *  
L4    *     *     *     *

其中*是显示行/列组合的汇总结果。

我正在计算高斯混合模型的KL散度。对于每对行,我计算“前”分布的混合和“后”分布的混合,然后计算这两种混合之间的差异。每个行对提供执行计算所需的8个参数,并将每个类别与算术平均值进行汇总。因此,在此示例中,我将执行144个不同的计算(因为有12x12行配对)并将它们分类为16个类别(L1&L1,L1&L2,L1&L3,L1&L4,L2&L1等),每个类别将是9个测量对的平均值在每个类别中。

我已经找到了用于计算的代码,但是我看不到如何逐步完成所有组合并组织结果。我曾考虑过为每个行对计算所需的值,然后根据“ Picture_Type”对将它们进行分箱,但我看不出如何实现这一点。

我一直在寻找其他代码示例,并且发现了可能有用的点点滴滴,但我看不到如何将它们组合在一起。我不熟悉这一切,并且正在工作中即时学习,但是如果有人能指出我正确的方向,我当然会很感激的。

1 个答案:

答案 0 :(得分:1)

我可能会为您提供部分答案,但是由于我不清楚您的职能,因此我将把这一部分留给您。

第一步是获取所有可能的配对组合的列表:

from itertools import combinations as cb
pairs = list(cb(range(11), 2))
print(pairs)

[(0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6), (0, 7), (0, 8), (0, 9), (0, 10), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (1, 7), (1, 8), (1, 9), (1, 10), (2, 3), (2, 4), (2, 5), (2, 6), (2, 7), (2, 8), (2, 9), (2, 10), (3, 4), (3, 5), (3, 6), (3, 7), (3, 8), (3, 9), (3, 10), (4, 5), (4, 6), (4, 7), (4, 8), (4, 9), (4, 10), (5, 6), (5, 7), (5, 8), (5, 9), (5, 10), (6, 7), (6, 8), (6, 9), (6, 10), (7, 8), (7, 9), (7, 10), (8, 9), (8, 10), (9, 10)]

如果您要寻找任一方向的所有可能组合,请使用itertools.product

如果将其中一对插入df.loc,则会得到:

df.loc[(0,1),:]

给予...

 Picture_Type  Before Mean  Before StdDev  After Mean  After StdDev
0           L1            9            1.0           6           0.7
1           L1           10            1.1           7           0.8

然后遍历这些对以创建所有行组合,此时您可以应用函数并重新创建新的数据框。

for n in range(len(pairs)):
    print('\npair...', pairs[n])
    df_pair = df.loc[pairs[n],:]
    s1 = df_pair.iloc[0]
    s2 = df_pair.iloc[1]

    print("Series 1\n", s1)
    print("Series 2\n", s2)



pair... (0, 1)
Series 1
 Picture_Type      L1
Before Mean        9
Before StdDev      1
After Mean         6
After StdDev     0.7
Name: 0, dtype: object
Series 2
 Picture_Type      L1
Before Mean       10
Before StdDev    1.1
After Mean         7
After StdDev     0.8
Name: 1, dtype: object

pair... (0, 2)
Series 1
 Picture_Type      L1
Before Mean        9
Before StdDev      1
After Mean         6
After StdDev     0.7
Name: 0, dtype: object
Series 2
 Picture_Type      L1
Before Mean       11
Before StdDev    1.2
After Mean         8
After StdDev     0.9
Name: 2, dtype: object

...etc...

**编辑

我将尝试添加您可能要查找的其余部分,但是我不确定这些方程式,因此我将使用一个简单的替代方程式。

OK为了简单起见,让您在两行中将Before Mean添加到Before StdDev,将After Mean添加到After StdDev,而不是将它们彼此相减。

如果将每对输入到df.loc中,则会得到以下内容:

result_dict = {}
for n in range(len(pairs)):
    df_pair = df.loc[pairs[n],:]
    s1 = df_pair.iloc[0]
    s2 = df_pair.iloc[1]

    s1_b = s1['Before Mean'] + s1['Before StdDev']
    s1_a = s1['After Mean'] + s1['After StdDev']
    s2_b = s2['Before Mean'] + s2['Before StdDev']
    s2_a = s2['After Mean'] + s2['After StdDev']

    result = (s1_a - s1_b) - (s2_a - s2_b)

    result_dict[pairs[n]] = s1['Picture_Type'], s2['Picture_Type'], result

df_result = pd.DataFrame.from_dict(result_dict).T

df_result.columns = ['PT1', 'PT2','result']   
df_result.groupby(["PT1", "PT2"]).sum().unstack(1)


   result                  
PT2     L1    L2    L3    L4
PT1                         
L1     0.0   0.0  38.7  40.2
L2     0.0   0.0  38.7  40.2
L3   -38.7 -38.7   0.0  14.4
L4   -40.2 -40.2 -14.4   0.0