忍受我的这一次吧,我已经为这个伤脑筋好几个小时了。你知道吗
考虑这些数据
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()
,因为它们应该返回相同的输出。
但是,addrj
输入了她的名字作为c
和d
,而nameb
输入了她的地址作为z
和n
,而e
输入了两次正确的地址,但第三次输入错误。因此,上述两个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
。我想尝试分配新的名字,可以正确地识别重复的名字或地址,但不知道如何做到这一点。感谢您的帮助。你知道吗
如果我理解正确,您可以创建从地址到名称的映射。然后用此映射覆盖名称,并按正常方式执行
GroupBy
:由
addr
产生的初始drop_duplicates
的工作原理是假设为任何name
输入的第一个地址是正确的。你知道吗另一种方法:
说明:
首先使用^{} 对
addr
列中的每个组进行编号然后groupby返回name和sum
df.groupby('name',as_index=False).sum()
现在,相同的地址行将具有相同的组号,因此您可以在} 函数和
group
列上再次分组,并使用^{apples = 'sum'
和name = first or last
来保留名称的第一个/最后一个实例。你知道吗然后只需对值进行排序并重置索引即可获得输出。你知道吗
相关问题 更多 >
编程相关推荐