如何计算字典中各种字符串的实例数

时间:2017-01-22 16:49:01

标签: python dictionary counter

我有一个大型字典(10,000多个条目)的ReviewIDs。字典有两个键,第一个是ReviewID#,第二个是Review的语言。

我的任务是计算每种语言的评论总数,然后将其显示在条形图中。

import pandas as pd
import csv
import matplotlib.pyplot as plt
import sys
RevDict = {}
with open('ReviewID.txt','r') as f:
for line in f:
    a,b = line.split(":")
    RevDict[a] = str(b)

这导致字典看起来像这样:

enter image description here

我的想法是将字典转换为Dataframe,其中Review ID为一列,语言为第二列。然后我可以使用计数器遍历行,最后得到每种语言的最终计数。这很容易转换成条形图。

不幸的是,我无法弄清楚如何做到这一点。

我还怀疑更加pythonic的方法是简单地计算字典本身中每个字符串的实例数,而不是通过制作数据帧的步骤。我试过这个:

from collections import Counter
Counter(k['b'] for k in data if k.get('b'))

抛出以下错误:

属性错误:' str'对象没有属性' get'

2 个答案:

答案 0 :(得分:2)

使用collections.Counter

import collections as coll

data = {
  'A': 'English',
  'B': 'German',
  'C': 'English'
} 

print(coll.Counter(data.values()))

--output:--
Counter({'English': 2, 'German': 1})

使用pandas

import pandas as pd

data = {
    'A': 'fr\n',
    'B': 'de\n',
    'C': 'fr\n',
    'D': 'de\n',
    'E': 'fr\n',
    'F': 'en\n'
}

df = pd.DataFrame(
    {
        'id': list(data.keys()),
        'lang': [val.rstrip() for val in data.values()],
    }
)

print(df)

输出:

  id lang
0  B   de
1  A   fr
2  F   en
3  D   de
4  E   fr
5  C   fr
grouped = df.groupby('lang')
print(grouped.size())

输出:

lang
de    2
en    1
fr    3

对评论的回应

Plotting

import collections as coll
import matplotlib.pyplot as plt
import numpy as np
from operator import itemgetter

data = {
    'A': 'fr\n',
    'B': 'de\n',
    'C': 'fr\n',
    'D': 'de\n',
    'E': 'fr\n',
    'F': 'en\n'
}

counter = coll.Counter(
    [val.rstrip() for val in data.values()]
)

langs, lang_counts = zip(
    *sorted(counter.items(), key=itemgetter(1))
)
total_langs = sum(lang_counts)

bar_heights = np.array(lang_counts, dtype=float) / total_langs
x_coord_left_side_of_bars = np.arange(len(langs))
bar_width = 0.8

plt.bar(
    x_coord_left_side_of_bars,
    bar_heights,
    bar_width,
)

plt.xticks(  
    x_coord_left_side_of_bars + (bar_width * 0.5),  #position of tick marks
    langs  #labels for tick marks
)
plt.xlabel('review language')
plt.ylabel('% of all reviews')

x = plt.plot()
#plt.show()  #Can use show() instead of savefig() until everything works correctly
plt.savefig('lang_plot.png')

情节:

enter image description here

答案 1 :(得分:1)

for k in data循环中,每个k都是一个字符串键(评论ID)。字符串没有.get()方法,原始变量b也不会对此循环产生任何影响。

如果您想计算数值,只需将字典的值直接传递给Counter

Counter(data.values())

您可能希望先删除换行符:

for line in f:
    review_id, lang = line.split(":")
    RevDict[review_id] = lang.strip()