Построение фрейма данных на основе двух других фреймов данных

#python #pandas #dataframe

Вопрос:

Мой фрейм данных выглядит следующим образом:

 df=
name   group  feedback     question
a      g1     False        abc
a      g1     True         abc
a      g1     True         xyz
b      g1     True         xyz
b      g1     True         abc
c      g1     False        def
d      g2     False        xyz
d      g2     True         xyz
e      g2     True         xyz
f      g3     True         abc
f      g3     True         www
g      g3     False        xyz
h      g4     True         www
h      g4     True         qqq
i      g4     False        xyz
 

У меня также есть фрейм данных, который содержит пары этих групп (и некоторые другие столбцы, которые не имеют значения). Обычно, но НЕ всегда содержит все возможные пары.

 df_2=
Group1   Group2    Value
g1       g2        0.25
g1       g3        0.50
g2       g3        0.25
g3       g4        0.50 
 

Я хочу создать новый фрейм данных со следующим заголовком:

 Group1   Group2   question    ScoreGroup1    ScoreGroup2
 

Это question будут общие вопросы, на которые ответила каждая пара. Это ScoreGroup1 количество Trues/(Trues Falses) ответов на этот вопрос для Group1 , аналогично для Group2 . Итак, в приведенном выше случае:

 Group1   Group2   question      ScoreGroup1         ScoreGroup2
g1       g2       xyz                     1                0.66
g1       g3       abc                  0.66                   1
g1       g3       xyz                     1                   0
g2       g3       xyz                  0.66                   0
g3       g4       www                     1                   1
g3       g4       xyz                     0                   0
 
 

Что я делал до сих пор: группировка по группам в исходном фрейме данных и feeback.mean() , но это дает мне только общий рейтинг групп. Мне нужно использовать сопряжение и общие вопросы. Я обнаружил, какие вопросы являются общими, выполнив:

 mutuals = df.groupby('group')['question'].apply(set)
 

Но как мне вычислить эти попарные оценки?

РЕДАКТИРОВАТЬ: это фреймы данных:

 df = {'name':['a', 'a', 'a', 'b', 'b', 'c', 'd', 'd', 'e', 'f', 'f', 'g', 'h', 'h', 'i'],
        'group':['g1', 'g1', 'g1', 'g1', 'g1', 'g1', 'g2', 'g2', 'g2', 'g3', 'g3', 'g3', 'g4', 'g4', 'g4'],
        'feedback': [False, True, True, True, True, False, False, True, True, True, True, False, True, True, False],
         'question': ['abc', 'abc', 'xyz', 'xyz', 'abc', 'def', 'xyz', 'xyz', 'xyz', 'abc', 'www', 'xyz', 'www', 'qqq', 'xyz]}

df_2 = {'Group1': ['g1', 'g1', 'g2', 'g3'],
        'Group2': ['g2', 'g3', 'g3', 'g4'],
        'Value': [0.25, 0.50, 0.25, 0.50]}
 

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

1. не могли бы вы опубликовать pd.DataFrame() — для создания этого набора данных и игры с ним?

Ответ №1:

Используйте DataFrame.merge то же DataFrame самое с удалением строк, если сначала одинаковые значения, затем агрегированное среднее:

 df = (df.merge(df, on='question', suffixes=('1','2'))
        .query('group1 != group2')
        .groupby(['group1','group2','question'], as_index=False)
        .mean())
print (df)
   group1 group2 question  feedback1  feedback2
0      g1     g2      xyz   1.000000   0.666667
1      g1     g3      abc   0.666667   1.000000
2      g1     g3      xyz   1.000000   0.000000
3      g1     g4      xyz   1.000000   0.000000
4      g2     g1      xyz   0.666667   1.000000
5      g2     g3      xyz   0.666667   0.000000
6      g2     g4      xyz   0.666667   0.000000
7      g3     g1      abc   1.000000   0.666667
8      g3     g1      xyz   0.000000   1.000000
9      g3     g2      xyz   0.000000   0.666667
10     g3     g4      www   1.000000   1.000000
11     g3     g4      xyz   0.000000   0.000000
12     g4     g1      xyz   0.000000   1.000000
13     g4     g2      xyz   0.000000   0.666667
14     g4     g3      www   1.000000   1.000000
15     g4     g3      xyz   0.000000   0.000000
 

И, наконец, создайте одинаковые имена столбцов для внутреннего соединения с помощью df_2 :

 d = {'Group1':'group1','Group2':'group2'}
df = df.merge(df_2[['Group1','Group2']].rename(columns=d))
print (df)
  group1 group2 question  feedback1  feedback2
0     g1     g2      xyz   1.000000   0.666667
1     g1     g3      abc   0.666667   1.000000
2     g1     g3      xyz   1.000000   0.000000
3     g2     g3      xyz   0.666667   0.000000
4     g3     g4      www   1.000000   1.000000
5     g3     g4      xyz   0.000000   0.000000