Терпи меня за это, я ломал голову над этим часами.
Рассмотрим эти данные
np.random.seed(2)
apples = np.random.randint(10,20,9)
df = pd.DataFrame({'name':list('aabbcdeee'), 'addr':list('mmznjjkkx'), 'apples':apples})[['name','addr','apples']]
Если name
то же самое, то это тот же человек, если addr
это то же самое, это также и тот же человек.Я хочу посчитать количество яблок, которое есть у каждого человека.Обычно это было бы тривиально:
In [50]: df[['apples', 'name']].groupby('name').sum()
Out[50]:
apples
name
a 36
b 28
c 18
d 17
e 38
или df[['apples', 'addr']].groupby('addr').sum()
, поскольку они должны возвращать один и тот же результат. НО , адрес j
ввел свое имя как c
и d
, в то время как имя b
ввел свой адрес как z
и n
, тогда как e
правильно ввел адрес дважды, ноиспортил 3-й раз.В результате обе вышеуказанные операции groupby
не учитывают количество яблок, которыми владеют некоторые люди.Идеальный вывод:
In [52]: %paste
pd.DataFrame({'name':list('aabbcceee'), 'addr':list('mmnnjjkkk'), 'apples':apples}).groupby('name').apples.sum()
## -- End pasted text --
Out[52]:
name
a 36
b 28
c 35
e 38
Name: apples, dtype: int32
Я могу идентифицировать индексы с ошибочными адресами или именами, используя наборы:
sameNames = df.name[df.name.duplicated()].index
sameAddr = df.addr[df.addr.duplicated()].index
sameNameORaddr = df.name[(df.name.duplicated() | df.addr.duplicated())].index
, так что ошибки здесь:
In [47]: sameNameORaddr.difference(sameNames).union(sameNameORaddr.difference(sameAddr))
Out[47]: Int64Index([2, 3, 4, 5, 8], dtype='int64')
, но я не могу понять, как использовать это для выполнения groupby
.Я думал о попытке присвоить новые имена, которые могут правильно идентифицировать дубликаты имен или адресов, но не могу понять, как это сделать.Любая помощь приветствуется.