【问题标题】:Python / Pandas - Performance - Calculating % of incidence of a value in a columnPython / Pandas - 性能 - 计算列中值的出现百分比
【发布时间】:2017-06-28 18:14:52
【问题描述】:

我有一个名为 target 的数据框:

target:

          group
170  64.22-1-00
72   64.22-1-00
121  35.12-3-00
99   64.22-1-00
19   35.12-3-00

我想创建一个名为 group_incidence 的新列,它是组出现在数据框中的频率比率。是这样计算的:

[total number of times that that 'group' appeared in the group column]/len(target.index)

看起来像这样:

          group   group_incidence 
170  64.22-1-00               0.6
72   64.22-1-00               0.6
121  35.12-3-00               0.4
99   64.22-1-00               0.6
19   35.12-3-00               0.4

我可以通过for 循环来做到这一点,但是由于这是一个很大的数据框,因此需要的时间太长。我相信如果我可以跳过 for 循环,我会获得可观的性能提升。

有没有办法在不通过 for 循环的情况下执行相同的操作?

【问题讨论】:

    标签: python performance pandas vectorization


    【解决方案1】:
    In [112]: df['group_incidence'] = df.groupby('group')['group'].transform('size') / len(df)    
    
    In [113]: df
    Out[113]:
              group group_incidence
    170  64.22-1-00             0.6
    72   64.22-1-00             0.6
    121  35.12-3-00             0.4
    99   64.22-1-00             0.6
    19   35.12-3-00             0.4
    

    【讨论】:

    • 可能在apply 之外有len(df)df.groupby('group')['group'].transform('count')/len(df)
    【解决方案2】:

    方法#1

    一种 NumPy 方法是 -

    _,tags, c = np.unique(df.group.values, return_counts=1, return_inverse=1)
    df['group_incidence'] = (c/c.sum())[tags]
    

    示例运行 -

    In [584]: df
    Out[584]: 
              group
    170  64.22-1-00
    72   64.22-1-00
    121  35.12-3-00
    99   64.22-1-00
    19   35.12-3-00
    
    In [585]: _,tags, c = np.unique(df.group.values, return_counts=1, return_inverse=1)
    
    In [586]: df['group_incidence'] = (c/c.sum())[tags]
    
    In [587]: df
    Out[587]: 
              group  group_incidence
    170  64.22-1-00              0.6
    72   64.22-1-00              0.6
    121  35.12-3-00              0.4
    99   64.22-1-00              0.6
    19   35.12-3-00              0.4
    

    方法#2

    另一个有点混乱/低级 NumPy 调整的想法是获得性能 -

    def argsort_unique(idx):
        # Original idea : http://stackoverflow.com/a/41242285/3293881 by @Andras
        n = idx.size
        sidx = np.empty(n,dtype=int)
        sidx[idx] = np.arange(n)
        return sidx
    
    def group_ratios_tagged(a):
        sidx = a.argsort()
        b = a[sidx]
    
        m = np.concatenate(( [False], b[1:] != b[:-1] ))
        sep_idx = np.concatenate(([0], np.flatnonzero(m), [a.size]))
        idx = m.astype(int)
        np.maximum.accumulate(idx, out=idx)
    
        c = sep_idx[1:] - sep_idx[:-1]
        h = (c/c.sum())[idx]
        out = h[argsort_unique(sidx)]
        return out
    

    示例运行(如何使用)-

    In [659]: df = pd.read_clipboard()
    
    In [660]: df
    Out[660]: 
              group
    170  64.22-1-00
    72   64.22-1-00
    121  35.12-3-00
    99   64.22-1-00
    19   35.12-3-00
    
    In [661]: df['group_incidence'] = group_ratios_tagged(df.group.values)
    
    In [662]: df
    Out[662]: 
              group  group_incidence
    170  64.22-1-00              0.6
    72   64.22-1-00              0.6
    121  35.12-3-00              0.4
    99   64.22-1-00              0.6
    19   35.12-3-00              0.4
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-06-13
      • 2019-01-26
      • 1970-01-01
      • 1970-01-01
      • 2021-10-17
      • 2022-11-21
      • 1970-01-01
      相关资源
      最近更新 更多