#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