Pandas - 计算并获取列中字符串值的唯一出现次数

Posted

技术标签:

【中文标题】Pandas - 计算并获取列中字符串值的唯一出现次数【英文标题】:Pandas - Count and get unique occurrences of string values from a column 【发布时间】:2018-03-26 09:34:55 【问题描述】:

我有一列有 800 多行,如下所示:

0                            ['Overgrow', 'Chlorophyll']
1                            ['Overgrow', 'Chlorophyll']
2                            ['Overgrow', 'Chlorophyll']
3                               ['Blaze', 'Solar Power']
4                               ['Blaze', 'Solar Power']
5                               ['Blaze', 'Solar Power']
6                               ['Torrent', 'Rain Dish']
7                               ['Torrent', 'Rain Dish']
8                               ['Torrent', 'Rain Dish']
9                            ['Shield Dust', 'Run Away']
10                                         ['Shed Skin']
11                       ['Compoundeyes', 'Tinted Lens']
12                           ['Shield Dust', 'Run Away']
13                                         ['Shed Skin']
14                                   ['Swarm', 'Sniper']
15             ['Keen Eye', 'Tangled Feet', 'Big Pecks']
16             ['Keen Eye', 'Tangled Feet', 'Big Pecks']
17             ['Keen Eye', 'Tangled Feet', 'Big Pecks']

我想要什么?

    我想统计每个字符串值出现的次数。 我还想将唯一的字符串值排列到一个列表中。

这是我为获得第二部分所做的工作:

list_ability = df_pokemon['abilities'].tolist()
new_list = []
for i in range(0, len(list_ability)):
    m = re.findall(r"'(.*?)'", list_ability[i], re.DOTALL)
    for j in range(0, len(m)):
        new_list.append(m[j])

list1 = set(new_list)  

我可以将唯一的字符串值放入一个列表中,但是有更好的方法吗?

示例:

'过度生长' - 3

'叶绿素' - 3

'火焰' - 3

'Sheild Dust' - 2 .... 以此类推

(顺便说一下,数据框df_pokemon中的列名是'abilities'。)

【问题讨论】:

你试过from collections import Counter; counts = df_pokemon.abilities.map(Counter).sum()吗? @JonClements 它正在返回每个字母和特殊字符的出现次数.. @JonClements 提到的标题是否适合这个问题? 【参考方案1】:

由于值是字符串,您可以使用正则表达式并拆分将它们转换为列表,然后使用 itertools 就像评论中提到的@JonClements 一样计数,即

from collections import Counter
count  = pd.Series(df['abilities'].str.replace('[\[\]\']','').str.split(',').map(Counter).sum())

输出:

大啄木鸟 3 叶绿素 3 雨碟 3 逃跑 2 狙击手 1 太阳能 3 纠结的脚 3 有色镜片 1 火焰 3 复眼 1 敏锐的眼光 3 杂草丛生 3 蜕皮 2 盾尘2 群 1 洪流 3 数据类型:int64 数据类型:int64

仅列出唯一值然后count[count==1].index.tolist()

['Sniper', 'Tinted Lens', 'Compoundeyes', 'Swarm']

用于制作索引列表然后

count.index.tolist()

【讨论】:

这就像一个魅力。有没有更好的方法来完成我对问题的第二部分所做的事情? 不。但是获得count 的索引会给出唯一的出现。不管怎么说,还是要谢谢你!顺便说一句,我希望这个标题适合这个问题。 请注意,如果你的技能名称中有,(或转义字符串分隔符或"作为字符串分隔符,因为其中使用了'),那么此代码将错误地拆分它与 ast.literal_eval 方法相反,它会根据 Python 列表的规则正确解析它。 @JonClements 我同意,但我认为能力不包含,,因为它不是一个句子,而是一个短语或动词。它可能是列表转换为字符串。【参考方案2】:

使用value_counts

In [1845]: counts = pd.Series(np.concatenate(df_pokemon.abilities)).value_counts()

In [1846]: counts
Out[1846]:
Rain Dish       3
Keen Eye        3
Chlorophyll     3
Blaze           3
Solar Power     3
Overgrow        3
Big Pecks       3
Tangled Feet    3
Torrent         3
Shield Dust     2
Shed Skin       2
Run Away        2
Compoundeyes    1
Swarm           1
Tinted Lens     1
Sniper          1
dtype: int64

对于独特的价值,你可以

In [1850]: counts.index.tolist()
Out[1850]:
['Rain Dish','Keen Eye', 'Chlorophyll', 'Blaze', 'Solar Power', 'Overgrow', 
 'Big Pecks', 'Tangled Feet', 'Torrent', 'Shield Dust', 'Shed Skin', 'Run Away',
 'Compoundeyes', 'Swarm', 'Tinted Lens', 'Sniper']

或者,

In [1849]: np.unique(np.concatenate(df_pokemon.abilities))
Out[1849]:
array(['Big Pecks', 'Blaze', 'Chlorophyll', 'Compoundeyes', 'Keen Eye',
       'Overgrow', 'Rain Dish', 'Run Away', 'Shed Skin', 'Shield Dust',
       'Sniper', 'Solar Power', 'Swarm', 'Tangled Feet', 'Tinted Lens',
       'Torrent'],
      dtype='|S12')

注意 - 如Jon's comments 中指出的,如果type(df_pokemon.abilities[0]) 不是list,则首先转换为列表

import ast
df_pokemon.abilities = df_pokemon.abilities.map(ast.literal_eval)

详情

In [1842]: df_pokemon
Out[1842]:
                              abilities
0               [Overgrow, Chlorophyll]
1               [Overgrow, Chlorophyll]
2               [Overgrow, Chlorophyll]
3                  [Blaze, Solar Power]
4                  [Blaze, Solar Power]
5                  [Blaze, Solar Power]
6                  [Torrent, Rain Dish]
7                  [Torrent, Rain Dish]
8                  [Torrent, Rain Dish]
9               [Shield Dust, Run Away]
10                          [Shed Skin]
11          [Compoundeyes, Tinted Lens]
12              [Shield Dust, Run Away]
13                          [Shed Skin]
14                      [Swarm, Sniper]
15  [Keen Eye, Tangled Feet, Big Pecks]
16  [Keen Eye, Tangled Feet, Big Pecks]
17  [Keen Eye, Tangled Feet, Big Pecks]

In [1843]: df_pokemon.dtypes
Out[1843]:
abilities    object
dtype: object

In [1844]: type(df_pokemon.abilities[0])
Out[1844]: list

【讨论】:

从 OP 对帖子的评论来看 - 看起来需要 df_pokemon.abilities.map(ast.literal_eval) 才能首先将它们放入列表中...... @Zero 让我明确指出abilities 列中的值是字符串。不存在任何列表。所以当我输入 df_pokemon['abilities'][0] 它返回 "['Overgrow', 'Chlorophyll']" @JeruLuke -- 做df_pokemon.abilities = df_pokemon.abilities.map(ast.literal_eval) 然后我用 value_counts 提到的。

以上是关于Pandas - 计算并获取列中字符串值的唯一出现次数的主要内容,如果未能解决你的问题,请参考以下文章

获取bash中列中唯一值的计数

Python开发---37pandas

熊猫计算列中每个值的出现次数

宏以获取列中每个唯一值的范围

在pandas DataFrame中按列计算唯一字符串[关闭]

Pandas,对于一列中的每个唯一值,在另一列中获取唯一值