【问题标题】:Create a column of bools from a pandas DataFrame where True indicates existence of a string in a column从 pandas DataFrame 创建一列布尔值,其中 True 表示列中存在字符串
【发布时间】:2018-01-07 17:54:47
【问题描述】:

在过去三个月左右的时间里,我一直在使用 Pandas 进行数据分析(并自学 Pandas)。

我有一个如下所示的 Pandas DataFrame:

df

client_id    opp_id    opportunity_status
4312         80465     Closed Won
4312         34508     Closed Won
4312         56478     Pending
3456         29930     Closed Lost
3456         70331     Pending
3456         65203     Closed Won
5203         29930     Closed Lost
5203         70331     Pending
5203         65203     Closed Lost
5203         65203     Closed Lost

我想高效地创建第二个 DataFrame:

has_cw

client_id    has_closed_won_opp
4312         True
3456         True
5203         False

其中has_cw.client_id 是来自df.client_id 的唯一值,has_cw.has_closed_won_opp 是一个布尔值列表,其中True 表示df 中至少有一个“已结束获胜”机会。

除了以这种方式循环通过df 效率低下之外,我很难想出一个好的方法:

has_cw = dict()
for id in df.client_id.unique():
    has_cw_bool = 'Closed Won' is in list(df[df['client_id'] == id]['opportunity_status'])
    has_cw[id] = has_cw_bool

然后将has_cw dict 转换为DataFrame。

我怎样才能有效地做到这一点?提前致谢!

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    您可以使用groupby.agg,为每个client_id检查是否有任何opportunity_status等于Closed Won

    df.groupby('client_id', as_index=False).opportunity_status.agg(lambda x: x.eq('Closed Won').any())
    
    # client_id   opportunity_status
    #0     3456                 True
    #1     4312                 True
    #2     5203                False
    

    或者更快的版本:

    df.opportunity_status.eq('Closed Won').groupby(df.client_id).any().reset_index()
    
    #   client_id   opportunity_status
    #0       3456                True
    #1       4312                True
    #2       5203               False
    

    %timeit df.groupby('client_id', as_index=False).opportunity_status.agg(lambda x: x.eq('Closed Won').any())
    # 100 loops, best of 3: 4.84 ms per loop
    
    %timeit df.opportunity_status.eq('Closed Won').groupby(df.client_id).any().reset_index()
    # 1000 loops, best of 3: 2.06 ms per loop
    

    【讨论】:

    • 我喜欢更快的版本。我需要先训练自己这样想。 +1
    • @Psidom 很好的解决方案,我认为可能有一个单行。谢谢!
    猜你喜欢
    • 2018-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-05
    • 2015-03-09
    • 2021-10-22
    • 1970-01-01
    • 2018-08-25
    相关资源
    最近更新 更多