Другой подход
Первая группа в BookID
и список всех авторов в каждой книге (т.е. список всех авторов в группе)
combos = df.groupby('BookID').agg(lambda x: list(x)).reset_index(drop=False)
print(combos)
BookID Author
0 1 [John, Alex, Jenna]
1 2 [John, Alex]
2 3 [John]
3 4 [Alex, Mary, Max]
Далее, объединить сОсновные данные, BookID
, для получения всех авторов для каждого автора
merged = combos.merge(df, how='inner', on='BookID')
print(merged)
BookID Author_x Author_y
0 1 [John, Alex, Jenna] John
1 1 [John, Alex, Jenna] Alex
2 1 [John, Alex, Jenna] Jenna
3 2 [John, Alex] John
4 2 [John, Alex] Alex
5 3 [John] John
6 4 [Alex, Mary, Max] Alex
7 4 [Alex, Mary, Max] Mary
8 4 [Alex, Mary, Max] Max
Author_x
- полный список авторов, включающий Author_y
.Теперь можно сравнивать полный список авторов (Author_x
) с каждым отдельным / уникальным автором (Author_y
), используя следующий подход
- Создание дикта, ключи которого уникальны
Author_y
значения (то есть уникальные авторы) и значения являются пустыми списками - Итерация по каждой паре ключ-значение в dict
- слайд объединенного кадра данных с шага выше с использованием столбца
Author_y
;это дает всех авторов для автора в ключе dict - из среза, получить список всех авторов (
Author_x
) в виде сведенного списка - расширить пустой список с помощью разница между сплющенным списком (все авторы) и ключом dict
d = {auth:[] for auth in df['Author'].unique()}
for k,v in d.items():
all_auths = merged[merged['Author_y']==k]['Author_x'].values.tolist()
auths = [coauths for nested in all_auths for coauths in nested]
v.extend(list(set(auths) - set([k])))
Наконец, поместите в DataFrame
и посчитайте ненулевые значения для строки
cnames = ['coauth'+str(k) for k in range(1,len(d))]
df_summary = pd.DataFrame.from_dict(d, orient='index', columns=cnames)
df_summary['Num_Unique_CoAuthors'] = df_summary.shape[1] - df_summary.isna().sum(axis=1)
print(df_summary)
author coauth1 coauth2 coauth3 coauth4 Num_Unique_CoAuthors
0 John Alex Jenna None None 2
1 Alex Max John Mary Jenna 4
2 Jenna John Alex None None 2
3 Mary Max Alex None None 2
4 Max Alex Mary None None 2
Расширенный регистр данных
Если основные данные содержат одного автора (т.е. без соавторов), то этот метод печатает ноль для этой строки
Здесьэто фиктивная строка, добавленная к данным, с одним автором
print(df)
BookID Author
0 1 John
1 1 Alex
2 1 Jenna
3 2 John
4 2 Alex
5 3 John
6 4 Alex
7 4 Mary
8 4 Max
9 5 Tom
А вот вывод
author coauth1 coauth2 coauth3 coauth4 Num_Unique_CoAuthors
0 John Jenna Alex None None 2
1 Alex Mary John Jenna Max 4
2 Jenna John Alex None None 2
3 Mary Max Alex None None 2
4 Max Mary Alex None None 2
5 Tom None None None None 0
Начальный ответ
Вы пробовали groupby
с sum
агрегацией
df.groupby(['Author'])['BookID'].sum()