python - 在 pandas DataFrame 中每组选择 1 个 True,1 个 False

标签 python pandas

我有一个包含约 100 万行和约 10 万个独特事件的 DataFrame。有 1 列 Won,每个事件 1 行设置为 True,事件中的每一行都设置为 False。

即,

Event ID  Runner ID  Won
 E1        R1        True
 E1        R2        False
 E1        R3        False
 E2        R4        True
 E2        R5        False
 E2        R6        False

我最终想要的是一个平衡的 DataFrame,每组只有 1 个获胜者,只有 1 个非获胜者。

即,

Event ID  Runner ID  Won
 E1        R1        True
 E1        R3        False
 E2        R4        True
 E2        R5        False

我不关心每个项目选出哪个非获胜者,只要有 1 个获胜者,一个非获胜者即可。

对于 pandas,我已经尝试了一些东西,选择获胜者和非获胜者,

_won = df.Won
winners = df[_won]

non_winners = df[~_won]

但我所见过的每个过程,并尝试在每场比赛中选择 1 名非获胜者都非常缓慢 - 每场比赛只有几秒钟(当你有 10 万场比赛时,这在 IMO 是不合理的)。

一次性使用groupapply

new_df = winners.append(
    non_winners
    .groupby('Event ID')
    .apply(lambda grp: grp.sample(1))

遍历 groupby,

for event_id, grp in non_winners.groupby('Event ID'):
    winners.append(grp.sample(1))

迭代获胜者中的事件 ID,

event_ids = set(winners['Event ID'].drop_duplicates())
for event_id in event_ids:
    winners.append(
        non_winners[non_winners['Event ID'] == event_id].sample(1))

但在处理 ~100 万和 ~100k 事件时,每个选项似乎都非常慢。

最佳答案

使用groupbyhead

df.groupby(['Event ID', 'Won']).head(1)

  Event ID Runner ID    Won
0       E1        R1   True
1       E1        R2  False
3       E2        R4   True
4       E2        R5  False

只要您对输出中保留的内容不挑剔,因为输出是平衡的。


还有 drop_duplicates

df.drop_duplicates(subset=['Event ID', 'Won'], keep='last') 
# or keep='first', it doesn't matter

  Event ID Runner ID    Won
0       E1        R1   True
2       E1        R3  False
3       E2        R4   True
5       E2        R6  False

最后,如果你想实现混洗,预先调用sample:

(df.sample(frac=1)
   .sort_values(by=['Event ID'])
   .drop_duplicates(['Event ID', 'Won'])
)

  Event ID Runner ID    Won
2       E1        R3  False
0       E1        R1   True
4       E2        R5  False
3       E2        R4   True

关于python - 在 pandas DataFrame 中每组选择 1 个 True,1 个 False,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51046863/

相关文章:

python - 在python OpenCV中以退出代码134(被信号6:SIGABRT中断)完成的过程

python - 使用不可订阅的对象创建文本文件

python - 在 Pandas 中转置 MultiIndex

python - Pandas 用列表替换列值

python - 为什么当我尝试对这个 numpy 数组求和时 Python 会崩溃?

python - Cython 是否将导入的模块编译为二进制文件的一部分?

python pandas - 使用 2 列作为引用进行映射

python - 使用 Pandas 数据框和嵌套在 Python 中的循环的基于项目的协作过滤器的瓶颈

python - 聚合数据框并计算每个类别

javascript - POST 文件上传的 django JsonResponse