美文网首页
day_3:文件读取操作,字符串处理, counter,正则表达

day_3:文件读取操作,字符串处理, counter,正则表达

作者: hxc92 | 来源:发表于2017-11-02 15:49 被阅读0次

文件读取写入

f = open('文件路径','r')  # 'w''r''wr'等都是决定是以写、读、读写方式打开文件
f.close()  # 用open打开文件的话必须记得close,因为对文件的读写都不是马上完成的,用close相当于提醒python赶紧干活然后结束

with open('path') as f:  # 使用with就免去了close,在with结束后自动close
     对f的处理

with fileinput.input(files='path') as f:  # 这里返回的是一个能返回文本每一行的迭代器
    for line in f:
        对每一行的处理


2017.12.15
补上一句

f.read(): 直接读取文件全部内容,str形式
f.readline():读取一行,str形式
f.readlines():读取所有行,列表形式,每一行都是列表的一个元素,元素是str形式

字符串处理

官方文档4.7.1,字符串方法

这部分东西好多看的头疼。。。。以下是我尝试过的

str = ‘ac4abc5bc’
str.strip('abc')  
'''
这个只能用来去除首部和尾部的指定字符,注意是字符而不是字符串;然后按照这个str来看的话会把a去掉,然后发现首部还有c可以去除,然后是4,
不能去除,那么首部清除完成;然后尾部,c可以,b可以,5不行,所以最后剩下‘4abc5’
最后返回一个新的字符串‘4abc5’
'''
str.split(sep=None, maxsplit=-1)
将字符串中的sep字符取出,并在这儿将字符串分割开,最后返回一个列表
不输入sep参数的话默认是按空格分隔,maxsplit决定了分隔的次数,-1时不限次数
str.replace(old, new[count])
将字符串中与old相同的部分用new替换,count部分决定了替换次数,默认为最大次,最后返回一个新的字符串
string.punctuation
# 这个返回的是'!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~'

counter

参考了这个词频统计的简易教程

counter提供了许多方便的计数功能,需要计数的时候都可以来看看collections库的官方文档,counter在8.3.2

官方文档中,counter是dict的一个子类,因此可以调用dict的方法。作为一个计数类,它允许value接受负值和0

counter有以下几种方法

Counter.element():按照键值,无序地将键返回,若键值为0则不返回对应的键

Counter.most_common(n):返回一个列表,其中是按照从大到小排列的counter中的键和键值,n决定的是返回前n个

Counter.subtract(iterable or mapping):对其进行c-d的减法

示例请看官方文档

正则表达式

个人使用正则表达式时都会参考的文章
以及官方文档

# 常用的调用格式
pattern = re.compile('待匹配的正则表达式')
match = re.search(pattern,待匹配文本)  #re.match和re.search都可以,主要区别在于match是从开头匹配,而search则是在文本任意部分匹配
# 匹配不成功的话会返回None,匹配成功则返回一个match对象
match.group()  # 获取匹配文本

几种方法



nltk库的词频统计

这是一篇关于自然语言处理基础的实战教程

用别人造好的轮子那是比较轻松了

import nltk
from nltk.corpus import stopwords
import fileinput
from nltk.tokenize import word_tokenize


class WordsFrequency:
    def __init__(self, path):
        self.path = path

    def get_text(self):
        with fileinput.input(files=self.path) as f:
            words = []
            for line in f:
                words.append(line)
        return words

    def clean_text(self):
        sr = stopwords.words('english')  # 包含了英语中的一些诸如is、a之类无意义的词
        clean_texts = list()
        for sentence in self.get_text():
            tokens = word_tokenize(sentence)
            for token in tokens:
                if token not in sr:
                    if token is not '.' and "'":  # 去除标点符号
                        clean_texts.append(token)
        return clean_texts

    def nltk_method(self):
        clean_tokens = self.clean_text()
        freq = nltk.FreqDist(clean_tokens)
        freq.plot(10, cumulative=False)  # ‘10’用于说明要统计的是词频数前10的

利用matplotlib作图

首先,这是它的官方文档

import matplotlib.pyplot as plt

plt.plot(x, x, label='linear')  # 一条以x为横轴,x为纵轴,标签为‘linear’的曲线 
plt.plot(x, x**2, label='square')
plt.plot(x, x**3, label='cubic')

plt.xlabel('xlabel')  # 给x轴添加标签‘xlabel’
plt.ylabel('ylabel')
plt.title('simple example')  # 添加标题‘simple example’
plt.legend()  # 在左上添加一个legend,显示三条曲线的表现和对应的颜色
plt.show()  # 显示图片

个人认为以上是在作图过程中较为常用的几个命令,用于给图添加说明。

虽然最后放弃该方案作图了。。。不过还是稍微介绍了下直方图


这次的内容是词频统计,因此用直方图较为合适,用于表示数据的分布情况(可以想象成统计相同数据出现的次数)

matplotlib.pyplot.hist(x, bins=None, range=None, density=None, weights=None, cumulative=False, bottom=None, histtype='bar', align='mid', orientation='vertical', rwidth=None, log=False, color=None, label=None, stacked=False, normed=None, hold=None, data=None, **kwargs)
'''
 这是它的调用格式,越后面的参数用的越不频繁,有时候可以查询
x:序列或者是数组类型
‘’‘

最后是对python之禅的词频分析

import nltk
from nltk.corpus import stopwords
import fileinput
from nltk.tokenize import word_tokenize
import re
import collections


class WordsFrequency:
    def __init__(self, path):
        self.path = path

    def get_text(self):
        with fileinput.input(files=self.path) as f:
            words = []
            for line in f:
                words.append(line)
        return words

    def clean_text(self):
        sr = stopwords.words('english')  # 包含了英语中的一些诸如is、a之类无意义的词
        clean_texts = list()
        pattern = re.compile('\W')
        for sentence in self.get_text():
            tokens = word_tokenize(sentence)  # 用word_tokenize将句子分成了单词,但是句点等符号还在
            for token in tokens:
                if token not in sr:
                    match = re.search(pattern,token)
                    if not match:  # 去除标点符号
                        clean_texts.append(token)
        return clean_texts

    def freq_dist(self):
        freq = collections.Counter(self.clean_text())
        return freq

    def most_common(self, number):  # 统计频率最高的n个
        return self.freq_dist().most_common(number)

    def nltk_method(self):
        clean_tokens = self.clean_text()
        freq = nltk.FreqDist(clean_tokens)  # nltk库提供的词频统计
        freq.plot(30, cumulative=False)  # ‘10’用于说明要统计的是词频数前10的

sorted

一直对sorted如何指定参数key实现自定义排序,借此机会了解一下
看官方文档是个好习惯,真的,这是sorted的官方文档
这里还有一个官方的sorting how to

从一个可迭代对象的item中返回一个重新排序的list
sorted(iterable,[,key],[,reverse]):
iterable 是待排序的对象,reverse要为布尔值,决定正序和倒序;
key则是决定以什么作为排序的参考

sorted(counts_dict,key=lambda x:counts_dict[x],reverse=True)
# 以counts_dict中的counts_dict[x]即键值作为排序的参考

个人认为可以这样理解,sorted的排序依据是key中的操作对iterable中的元素逐个作用后得到的值,但并不是直接返回该值构成的序列,而是该值在iterable中所对应的值。

以下勉强算是一串实现sorted的粗略伪代码

List = [........]
List_sorted = list()
List_1 = dict()
List_1_cache = list()
key = func()
for element in List:
    List_1_cache = func(element)
    List_1[element] = func(element)
List_1_sorted = sorted(List_1_cache)
for element in List_1_sorted:
    List_sorted.append(element)

关于我所不知道的list

在看这篇文章的时候来自星球中叶宪克的分享
其中的一句让我很困惑

counts_dict={index:words.count(index) for index in words_index}  #其中的words.count()

这里的words是一个列表,因此查阅官方文档关于list的说明4.6.1

常用到的list操作.png

列出了一些我并不知道的事情

list = [[]] * 3
lsit[0].append(3) 
>>>[[3], [3], [3]]
'''创建时候并不是分别创建了3个[],而是将一个[]引用了三次来创建[[], [], []],因此对任意一个[]的改动会同时影响list中的所有元素
但是如果是list[0] = 1,则不会同时影响三个元素
list1[0].append(1)这样的话则是[[1], [1], [1]]
'''
list1 = [[None, None]] * 3
list1[0][0] = 1 
>>>[[1, None], [1, None], [1, None]]   # 真的是excuse me了

这里官方还是只提到了reference,解释的并不是很清楚。我自己的理解是list1[0][0] = 1 ,lsit[0].append(3)操作对象都是原先的[None, None]和[]这样的列表,而创建列表用的是他们的reference,因此导致了整个列表的元素改变;而在list[0] = 1中更改的对象实际是list列表中的第一个元素

验证:
我尝试通过id检查来确定我的想法(从python之禅学到的)

list1 = [[None] * 2] * 3
print(id(list1[0]), id(list1[1]), id(list1[2]))
>>>2146680370248 2146680370248 2146680370248  # 这三个元素真特么的一模一样啊

list1[0][0] = 1
print(id(list1[0]), id(list1[1]), id(list1[2]))
>>>2732429341896 2732429341896 2732429341896  #这是分几次运行的,id不同是正常的

list2 = [[]] * 3
list2[0].append(1)
print(id(list2[0]), id(list2[1]), id(list2[2]))
>>>2231677759304 2231677759304 2231677759304

list2[0] = 1
print(id(list2[0]), id(list2[1]), id(list2[2]))
>>>1442337568 2231677759304 2231677759304

print(id(1))
>>>1442337568   # list2[0]与1指向了同一个对象

list1[0] = 1这一步实际上是将list1的第一个元素指向1这个对象了,而list1[0].append(1)则是在list1[0]所指向的[]对象中添加了1这个元素,第一段代码则是将list1[0]指向的[None, None]的第一个元素指向了0,并没改变list1[0]指向的对象

文字描述可能不够清晰,大家可以看看Python之禅关于变量和赋值个人认为对于理解我所说的有一定意义

  1. list[n],当n为负数的时候,实际上是这样调用的list[len(list)+n];-0不是负数
  2. 使用list[i ;j ; k]的时候实际的index是i + n * k(n < (j - i) / k)

看军哥代码

# -*- coding:utf-8 -*-
import io
import re

class Counter:
    def __init__(self, path):
        """
        :param path: 文件路径
        """
        self.mapping = dict()
        with io.open(path, encoding="utf-8") as f:  # 
            data = f.read()
            words = [s.lower() for s in re.findall("\w+", data)]
# re.findall(pattern, str):在匹配过程中不会发生对同一个字符多次匹配的状况,并且如果在首部和尾部匹配到了空格则会将其去除
            for word in words:
                self.mapping[word] = self.mapping.get(word, 0) + 1
# 这是一种常用的用于创建一个字典,其键值是键在word中出现的次数
# dict[key] = dict.get(key, default) +  1,get方法用来获取键值,参数key即键,default是表示在dict中若没有key这个键则创建一对以key为键、默认值为default的键值

    def most_common(self, n):
        assert n > 0, "n should be large than 0"
        return sorted(self.mapping.items(), key=lambda item: item[1], reverse=True)[:n]

if __name__ == '__main__':
    most_common_5 = Counter("importthis.txt").most_common(5)
    for item in most_common_5:
        print(item)

相关文章

  • day_3:文件读取操作,字符串处理, counter,正则表达

    文件读取写入 2017.12.15补上一句 字符串处理 官方文档4.7.1,字符串方法 这部分东西好多看的头疼。。...

  • Java_正则表达式 时间类

    正则表达式 正则表达式,又称规则表达式.常用于验证.搜索,查找(匹配),替换(只能操作字符串),编辑或处理文本正则...

  • go基本语法操作

    异常处理 异常类型error 异常捕获recover 异常抛出panic 字符串处理 字符串常用操作 正则表达式 ...

  • LINUX----正则表达式

    正则表达式就是处理字符串的方法,它以行为单位进行字符串的处理操作,正则表达式通过一些特殊符号的辅助,让用户轻松地完...

  • Python学习

    第十九天 正则表达式 正则表达式是一个强大的字符串处理技术,几乎任何和字符串有关的操作都可以使用正则表达式来完成,...

  • Linux11_ 正则表达式基本语法详解

    正则表达式处理文件内容都是字符,非numeric数据 字符串匹配的作用。几乎所有语言都支持正则表达式。 基础正则g...

  • 正则表达式 grep与sed的文本处理

    [正则表达式 grep与sed的文本处理] 一:整理正则表达式 正则表达式是对字符串操作的一种逻辑公式,就是用事先...

  • go 文本处理

    字符串操作 字符串转换 正则表达式

  • Python--之正则表达式一基础

    1.表达式基础正则表达式是一个非常强大的字符串处理工具,几乎任何关于字符串的操作都可以使用正则表达式来完成,经常和...

  • php方法大合集

    文件系统处理 数组常用函数 字符串常用函数 文件的属性 解析目录路径 遍历目录小例子 文件的基本操作 读取文件内容...

网友评论

      本文标题:day_3:文件读取操作,字符串处理, counter,正则表达

      本文链接:https://www.haomeiwen.com/subject/ivogpxtx.html