我有一个像这样的数据框:
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。我们可以假设这一次对于任何其他成员来说都不会相同。
在 pandas 中实现此目的的有效方法是什么?这里我只有一个事件作为示例,但我将有几个这样的事件,并且我需要为每个事件执行此操作。
最佳答案
您可以使用groupby
使用自定义函数 f
,该函数返回新列 is_leader
,对于与 具有相同
:时间
的所有行,返回 True
name
列中包含文本 leader
的行的时间
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
然后删除带有 leader
的行 boolean indexing
并将 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
关于python - 如何根据pandas中的某些列匹配行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40101925/