如何根据 pandas 中的某些列匹配行?
How to match rows based on certain columns in pandas?
我有一个这样的数据框:
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
结合使用,其中 return 新列 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
我有一个这样的数据框:
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
结合使用,其中 return 新列 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