Оценка функции с использованием всех возможных пар строк - PullRequest
0 голосов
/ 10 июля 2019

Используя панды в 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 Ответ

1 голос
/ 11 июля 2019

Возможно, у меня есть частичный ответ для вас, но, поскольку я не совсем понимаю ваши функции, я оставлю эту часть вам.

Первый шаг - получить список всех возможных парных комбинаций:

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...

** EDIT

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

OK. Допустим, для простоты вы добавляете «До среднего» к «До StdDev» и «После среднего» к «После» 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...