如何使用 Pandas groupby() 将列的逗号分隔项的字符串聚合到列表中?

Kub*_*888 5 aggregation python-3.x pandas pandas-groupby

我有如下数据:

NAME    ETHNICITY_RECAT TOTAL_LENGTH    3LETTER_SUBSTRINGS
joseph  fr              14              jos, ose, sep, eph
ann     en              16              ann
anne    ir              14              ann, nne
tom     en              18              tom
tommy   fr              16              tom, omm, mmy
ann     ir              19              ann
... more rows
Run Code Online (Sandbox Code Playgroud)

3LETTER_SUBSTRINGS 值是字符串,它捕获 NAME 变量的所有 3 字母子字符串。我想将它聚合到一个列表中,每个逗号分隔的项目按每一行附加到列表中,并被视为一个列表项。如下:

ETHNICITY_RECAT TOTAL_LENGTH            3LETTER_SUBSTRINGS
                min max mean            <lambda>
fr              2   26  13.22           [jos, ose, sep, eph, tom, oom, mmy, ...]
en              3   24  11.92           [ann, tom, ...]
ir              4   23  12.03           [ann, nne, ann, ...]
Run Code Online (Sandbox Code Playgroud)

我使用以下代码“完成”了它:

aggregations = {
    'TOTAL_LENGTH': [min, max, 'mean'], 
    '3LETTER_SUBSTRINGS': lambda x: list(x),
    }

self.df_agg = self.df.groupby('ETHNICITY_RECAT', as_index=False).agg(aggregations)
Run Code Online (Sandbox Code Playgroud)

问题是整个字符串“ann, anne”被认为是最终列表中的单个列表项,而不是将每个字符串都视为单个列表项,例如“ann”、“anne”。

我想看到子串的最高频率,但现在我得到了整个字符串的频率(而不是单个 3 个字母的子字符串),当我运行以下代码时:

from collections import Counter 
x = self.df_agg_eth[self.df_agg_eth['ETHNICITY_RECAT']=='en']['3LETTER_SUBSTRINGS']['<lambda>']
x_list = x[0]
c = Counter(x_list)
Run Code Online (Sandbox Code Playgroud)

我明白了:

[('jos, ose, sep, eph', 19), ('ann, nee', 5), ...]
Run Code Online (Sandbox Code Playgroud)

而不是我想要的:

[('jos', 19), ('ose', 19), ('sep', 23), ('eph', 19), ('ann', 15), ('nee', 5), ...]
Run Code Online (Sandbox Code Playgroud)

我试过:

'3LETTER_SUBSTRINGS': lambda x: list(i) for i in x.split(', '),
Run Code Online (Sandbox Code Playgroud)

但它说invalid syntax

Qua*_*ang 2

您要做的第一件事是将字符串转换为列表,然后它只是一个groupbywith agg

df['3LETTER_SUBSTRINGS'] = df['3LETTER_SUBSTRINGS'].str.split(', ')

df.groupby('ETHNICITY_RECAT').agg({'TOTAL_LENGTH':['min','max','mean'],
                                   '3LETTER_SUBSTRINGS':'sum'})
Run Code Online (Sandbox Code Playgroud)

输出:

                TOTAL_LENGTH                             3LETTER_SUBSTRINGS
                         min max  mean                                  sum
ETHNICITY_RECAT                                                            
en                        16  18  17.0                           [ann, tom]
fr                        14  16  15.0  [jos, ose, sep, eph, tom, omm, mmy]
ir                        14  19  16.5                      [ann, nne, ann]
Run Code Online (Sandbox Code Playgroud)