我有一个这样的数据框:
id date event name time
1 2016-10-01 A leader 12:45
2 2016-10-01 A AA 12:87
3 2016-10-01 A BB 12:45
事件中每个成员都有行,但是一行也有前导数据。我想要排除包含领导者数据的行,并添加一列is_leader
来表明成员是否是领导者。像这样:
id date event name time is_leader
2 2016-10-01 A AA 12:87 0
3 2016-10-01 A BB 12:45 1
所以,我知道id=3
是基于时间的领导者,这里两者都是12:45。我们可以假设这次对其他任何成员来说都不一样。
在熊猫中实现这一目标的有效方法是什么?在这里,我只举一个例子,但我有几个这样的事情,我需要为每个事件做这个。
答案 0 :(得分:3)
您可以将groupby
与自定义函数f
一起使用,对于与is_leader
相同的True
行,time
返回新列time
列leader
中包含文字name
的行:
print (df)
id date event name time
0 1 2016-10-01 A leader 12:45
1 2 2016-10-01 A AA 12:87
2 3 2016-10-01 A BB 12:45
3 1 2016-10-01 B leader 12:15
4 2 2016-10-01 B AA 12:15
5 3 2016-10-01 B BB 12:45
def f(x):
x['is_leader'] = x.time == x.ix[x['name'] == 'leader', 'time'].iloc[0]
return x
df= df.groupby('event').apply(f)
print (df)
id date event name time is_leader
0 1 2016-10-01 A leader 12:45 True
1 2 2016-10-01 A AA 12:87 False
2 3 2016-10-01 A BB 12:45 True
3 1 2016-10-01 B leader 12:15 True
4 2 2016-10-01 B AA 12:15 True
5 3 2016-10-01 B BB 12:45 False
具有lambda函数的一行解决方案:
df['is_leader'] = df.groupby('event')
.apply(lambda x: x.time == x.ix[x['name'] == 'leader', 'time'].iloc[0])
.reset_index(drop=True, level=0)
print (df)
id date event name time is_leader
0 1 2016-10-01 A leader 12:45 True
1 2 2016-10-01 A AA 12:87 False
2 3 2016-10-01 A BB 12:45 True
3 1 2016-10-01 B leader 12:15 True
4 2 2016-10-01 B AA 12:15 True
5 3 2016-10-01 B BB 12:45 False
然后按boolean indexing
删除leader
行,并将boolean
列投放到int
:
df = df[df.name != 'leader']
df.is_leader = df.is_leader.astype(int)
print (df)
id date event name time is_leader
1 2 2016-10-01 A AA 12:87 0
2 3 2016-10-01 A BB 12:45 1
4 2 2016-10-01 B AA 12:15 1
5 3 2016-10-01 B BB 12:45 0