ct = pd.crosstab(df.Name, df.Item)
d = {Name: [(name, val)
for name, val in ct.loc[ct.index != Name, ct.ix[Name] == 1]
.sum(axis=1).iteritems() if val]
for Name in df.Name.unique()}
>>> pd.DataFrame({'Name': d.keys(),
'People': [[t[0] for t in d[name]] for name in d],
'times': [[t[1] for t in d[name]] for name in d]})
Name People times
0 Richard [James, John, Tom] [1, 1, 1]
1 James [John, Richard, Tom] [1, 1, 1]
2 Tom [Frank, James, John, Paul, Richard] [1, 1, 2, 1, 1]
3 Frank [Tom] [1]
4 Paul [John, Tom] [1, 1]
5 John [James, Paul, Richard, Tom] [1, 1, 1, 2]
ОБЪЯСНЕНИЕ
перекрестный получает вас местоположение каждого имени по типу товара ,
>>> ct
Item A B C
Name
Frank 0 1 0
James 0 0 1
John 1 0 1
Paul 1 0 0
Richard 0 0 1
Tom 1 1 1
Эта таблица затем сокращается. Для каждого имени, на котором строится ключ, это имя удаляется из таблицы, и выбираются только столбцы, в которых это имя отображается.
Используя «Джон» в качестве примера:
>>> ct.loc[ct.index != 'John', ct.ix['John'] == 1]
Item A C
Name
Frank 0 0
James 0 1
Paul 1 0
Richard 0 1
Tom 1 1
Этот результат затем суммируются по строкам, чтобы получить результаты для Джона:
Name
Frank 0
James 1
Paul 1
Richard 1
Tom 2
dtype: int64
Эти результаты затем итерации упаковать их в пары кортежей и удалить случай, когда значение равно нулю (например, Фрэнк выше).
>>> [(name, val) for name, val in
ct.loc[ct.index != 'John', ct.ix['John'] == 1].sum(axis=1).iteritems() if val]
[('James', 1), ('Paul', 1), ('Richard', 1), ('Tom', 2)]
Это действие выполняется для каждого имени, используя понимание словаря.
>>> d
{'Frank': [('Tom', 1)],
'James': [('John', 1), ('Richard', 1), ('Tom', 1)],
'John': [('James', 1), ('Paul', 1), ('Richard', 1), ('Tom', 2)],
'Paul': [('John', 1), ('Tom', 1)],
'Richard': [('James', 1), ('John', 1), ('Tom', 1)],
'Tom': [('Frank', 1), ('James', 1), ('John', 2), ('Paul', 1), ('Richard', 1)]}
Этот словарь используется для создания желаемого dataframe с помощью вложенного списка понимание распаковывать пар кортежей.
В строке 2 вашей второй таблицы не должно быть «Джон [Том, Ричард, Джеймс, Пол] [2,1,1,1]», так как Иоанн и Павел оба находятся в пункте А? – Alexander