【问题标题】:Explode column of strings and count character frequencies分解字符串列并计算字符频率
【发布时间】:2018-09-25 16:17:33
【问题描述】:

我有一个包含 2 列的数据集,如下所示:

|group| |sequence|
A        BX
A        X
B        SFS
B        BCX
B        BSS*B1S
A        BBX

我想要一些方法来分组并找到每个字符的频率,得到这样的东西:

 |group| |char| |freq|
 A       B       3
 A       X       3
 B       S       5
 ...

【问题讨论】:

  • 两个 cmets 都工作得很好,我只是想知道我是否可以同时选择两个作为答案。

标签: python string pandas dataframe


【解决方案1】:

使用推导式创建元组列表。

c = pd.value_counts([(g, s) for g, S in df.values for s in S if s.isalpha()])

pd.DataFrame(
    np.column_stack([c.index.tolist(), c.values]),
    columns=df.columns.tolist() + ['freq']
)

  group sequence freq
0     B        S    5
1     A        B    3
2     B        B    3
3     A        X    3
4     B        F    1
5     B        C    1
6     B        X    1

【讨论】:

    【解决方案2】:

    这里有几种不同的方式来展示你的结果。

    在字符串上应用groupby.sum 将它们连接起来,之后我们可以应用pd.value_counts

    df = pd.DataFrame({'group': ['A', 'A', 'B', 'B', 'B', 'A'],
                       'sequence': ['BX', 'X', 'SFS', 'BCX', 'BSS*B1S', 'BBX']})
    
    res = df.groupby('group')['sequence'].sum().map(list).apply(pd.value_counts)\
            .fillna(0).astype(int).reset_index()
    
    res = res.loc[:, res.columns.str.isalpha()]
    
    print(res)
    
    #   group  B  C  F  S  X
    # 0     A  3  0  0  0  3
    # 1     B  3  1  1  5  1
    
    res2 = pd.melt(res, id_vars=['group']).sort_values(['group', 'variable'])
    res2 = res2[res2['value'] != 0].set_index(['group', 'variable'])
    
    #                 value
    # group variable       
    # A     B             3
    #       X             3
    # B     B             3
    #       C             1
    #       F             1
    #       S             5
    #       X             1
    
    print(res2)
    

    collections.Counter 可以实现更有效的变化:

    from collections import Counter
    
    res = df.groupby('group')['sequence'].sum().apply(Counter).apply(pd.Series)\
            .fillna(0).astype(int).reset_index()
    

    【讨论】:

      【解决方案3】:

      您可以使用基于repeat 的高效解决方案,然后使用groupby

      from itertools import chain
      
      # Step 1 - flatten your dataframe
      df = pd.DataFrame({
          'group' : df['group'].repeat(df.sequence.str.len()), 
          'char' : list(chain.from_iterable(df.sequence.tolist()))
      })
      # Step 2 - filter out characters and groupby on `group`
      df[df.char.str.isalpha()].groupby(['group', 'char']).size().reset_index(name='freq')
      

        group char  freq
      0     A    B     3
      1     A    X     3
      2     B    B     3
      3     B    C     1
      4     B    F     1
      5     B    S     5
      6     B    X     1
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-05-18
        • 2017-04-19
        • 2011-10-06
        • 2019-08-07
        • 1970-01-01
        • 1970-01-01
        • 2023-03-25
        相关资源
        最近更新 更多