本帖最后由 batsealine 于 2016-4-4 10:40 编辑
先举个例子展示脚本要干的事:
有两个文件 jd.txt 和 stem.txt jd.txt 中有“苏 eyo”, stem.txt中有"苏 ey",现要生成一个新文件里面为"苏 eyo ey",再具体一点:
jd.txt 是这样的:
木桨 fatr
本应 fatv
枰 faua
苏 eyo
stem.txt 是这样的(全部是单字):
苏 ey
枰 fa
要求生成的 new_jd.txt :
木桨 fatr
本应 fatv
枰 faua fa
苏 eyo ey
要求 new_jd.txt 中字的顺序不变,相当于只在 jd.txt 中部份字后加入一列构词码
文件下载地址(右键另存为):jd.txt stem.txt
我已经用for循环实现了,两个文件分别有18万行和3万行,这样下来需要15分钟左右,现在求一个更好的方法,如果有谁会 grep awk,也欢迎指点。
下面是我的代码:- # -*- encoding: UTF-8 -*-
- # 此脚本的作用是将stem.txt中的构词码加到指定的码表中,stem.txt从https://github.com/lotem/rime-forge/tree/master/zhengma处得来(在dict.ymal的最下面)
- # usage:add_stem.py filename/filepath
- # 它将在当前文件夹生成一个新文件,命名为 new_*
-
- import re
- import os
- import sys
- import codecs
- # 用codecs以指定编码打开文件很有效,不然有时会有错误
- filepath = sys.argv[1]
- filename = re.search(r'(?:.*/)?(.*)\.', filepath).group(1) #[/\\]用来兼容\路径和/路径, (?:..)?用来兼容没有路径只有文件名的情况
- newFilename = "new_" + filename + ".txt"
- f = codecs.open(filepath, "r", 'utf-8')
- lines = f.readlines() #readlines()能生成一个list
- f.close()
-
- f_stem = codecs.open(r'stem.txt', "r", 'utf-8')
- stemlines = f_stem.readlines()
- f_stem.close()
-
- newf = codecs.open(newFilename, "w", 'utf-8')
-
- for i,line in enumerate(lines):
- # enumerate这个方法是从网上找的可以方便的找出循环的次数
- words = line.split()
- myre = words[0]
- if (len(myre) == 1): # 只为单字查找构词码
- for stemline in stemlines:
- if (re.match(myre, stemline)): # 汉字可以直接用正则匹配
- line = line.strip('\r\n') + "\t" + stemline.split()[1] + '\n' # 用line.strip('\r\n')去除行尾的换行符,注意一定不要忘了'\r'
- break
- newf.write(line)
- if (i % 100 == 0):
- print(i)
- # 这里打印出行数是为了查看进度,因为整个过程大概要15分钟,当行数为18万时都差不多完了。
- newf.close()
复制代码 ############################## 分割线
用了版主的 OrderedDict 后,程序的运行时间只要1.1s,非常满意- # -*- encoding: UTF-8 -*-
- # 此脚本的作用是将stem.txt中的构词码加到指定的码表中,stem.txt从https://github.com/lotem/rime-forge/tree/master/zhengma处得来(在dict.ymal的最下面)
- # usage:add_stem.py filename/filepath
- # 它将在当前文件夹生成一个新文件,命名为 new_filename
-
- import re
- import os
- import sys
- import codecs
- from time import time
- from collections import OrderedDict # 待找相关资料,这是加快的速度的核心
-
- # 用codecs以指定编码打开文件很有效,不然有时会有错误
- filepath = sys.argv[1]
- filename = os.path.basename(filepath)
- newFilename = "new_" + filename
- f = codecs.open(filepath, "r", 'utf-8')
- lines = f.readlines() #readlines()能生成一个list
- f.close()
-
- f_stem = codecs.open(r'stem.txt', "r", 'utf-8')
- stemlines = f_stem.readlines()
- f_stem.close()
-
- newf = codecs.open(newFilename, "w", 'utf-8')
-
-
- # 先将stem.txt 的内容组成二元列表
- stemwords = []
- for stemline in stemlines:
- stemline_split = stemline.split()
- stemwords.append((stemline_split[0], stemline_split[1]))
-
- # 再stemwords这个二元列表变为有序的字典,具体的原理还不清楚
- stem = OrderedDict(stemwords)
-
-
- for i,line in enumerate(lines):
- # enumerate这个方法是从网上找的,可以方便的找出循环的次数
- word = line.split()[0]
- if (len(word) == 1 and stem.get(word)):
- # stem.get(word) 判断word在stem中是否存在,stem[word]找出word在stem.txt所对应的构词码
- line = line.strip('\r\n') + '\t' + stem[word] + '\n'
- newf.write(line)
-
- newf.close()
复制代码
|