统计词频

统计词频

"""
#统计1000w行的文件中,字符串出现的次数并排序,其中字符串以空格分割
#我认为需要考虑三个问题
1、大文件的读取,一行一行读入,避免一次性读入,内存溢出的情况
2、文件编码格式的处理,避免乱码
3、python中字典对象的排序,按value值排序
"""
import os
import chardet
def get_encoding(filename):
    """
    :param filename: 文件路径
    :return:  文件编码类型
    """
    try:
        f = open(filename,"rb")
        data = f.readline()
        f.close()
        encoding = chardet.detect(data)
        print(encoding)
        return encoding['encoding']
    except Exception as e:
        print("获取文件编码出错")

def count_word(filename):
    """
    :param filename: 文件路径
    :return: None 操作异常;
            ss 列表,列表中的每一个元素为包含两个元素的元组,
            元组的第一个元素为文中出现的字符串,第二个元素为其在文中出现的次数,按出现次数升序排序
    """
    if not os.path.exists(filename): #检查文件是否存在
        print("文件不存在")
        return None
    dic_c = {} #用字典来存储每个字符串出现的次数,key为字符串,value 为次数
    try:
        encoding_ = get_encoding(filename)  #获取文件编码方式,避免出现乱码
        with open(filename, "rb")as f:  # 以rb形式读入,速度会快
            for line in f: #一行一行读入,避免内存溢出的情况
                strings = line.split()  # 分割一行,以空格分隔
                for word in strings:
                    word = word.lower()  #全部转化为小写
                    if word not in dic_c.keys():  # 第一次出现
                        dic_c[word] = 1
                    else:
                        dic_c[word] += 1  # 出现次数加1

        sort_dic_c = sorted(dic_c.items(), key=lambda item: item[1],reverse=True)  # 按出现次数排序,升序 如果需要逆序的话,reverse=True即可
        word_count = []
        for i in sort_dic_c:
            word = i[0].decode(encoding_)  #对二进制串进行解码
            count = i[1]
            word_count.append((word,count))
        return  word_count
    except Exception as e: #出现异常,打印异常 ,返回None
        print("出现异常:",e)
        return None

你可能感兴趣的:(统计词频)