python构建带数字的古诗词数据集

一、数据准备:

全唐诗数据集https://github.com/todototry/AncientChinesePoemsDB
从郑州大学图书馆网站上爬取下来的全唐诗库,收录了唐代诗人2539人的诗作42863首,共计900卷。
该数据集格式为:每首诗一个txt文件,按照卷进行排序和命名。其中有一些为空白文件,总大小为5MB左右。
中华古诗数据集https://github.com/jackeyGao/chinese-poetry
唐宋两朝14000名古诗人,55000首唐诗,260000首宋词,用数据分析抽丝剥茧文化内涵。
该数据集格式为:每一千首诗词一个json文件,其中包含平仄、作者、诗句和题目。诗句均为繁体。

[
  {
    "strains": [
      "仄仄仄仄平仄仄,平平仄平○仄仄。", 
      "平平仄仄平仄平,仄仄平平?仄仄。"
    ], 
    "author": "宋太祖", 
    "paragraphs": [
      "欲出未出光辣達,千山萬山如火發。", 
      "須臾走向天上來,逐却殘星趕却月。"
    ], 
    "title": "日詩"
  }, 
  ...
]

二、全唐诗数据集处理

首先,将4万多个古诗词文件合并为一个大txt,每行一首诗。
为了去除空白文件,将文件读入集合后,将集合元素逐行写入txt中。
如果文件过多或过大,为防止内存溢出,可以使用os.path.getsize('./ks_accumulate.csv')判断文件是否为空,再逐个文件写入大txt。
分析发现部分诗句中含有括号,形如

先生自舞琴。(《三乐达节》)波上人如潘玉儿,掌中花似赵飞燕。(《采莲曲》,以上并见《乐书》)

部分诗句后含有多余文本,形如

弟子已攀桂,先生犹卧云。把得新诗草里论。枯井夜闻邻果落,废巢寒见别禽来。卷六百五十四

用正则表达式对这种文本进行处理,去除括号中的内容和诗句后多余内容。
其中还有少部分问题诗句,如包含多个句号的、有特殊符号的等等。

微官同侍苍龙阙,直谏偏推白马生。。
傩击鼓长笛,瘦鬼染面惟齿白。暗中拽茅鞭,。。倮足朱行戚戚。ń相顾笑声冲庭燎,桃弧射矢时独叫。
卷263_46【九日登高】严维诗家九日怜芳菊,迟客高斋瞰浙江。汉浦浪花摇素壁,西陵树色入秋窗。木奴向熟悬金实,桑落新开泻玉缸。四子醉时争讲德,笑论黄霸屈为邦。
五杂组,四豪客。往复还,阡与陌。不得已,长沙谪。__张荐五杂组,五辛盘。往复还,马上鞍。不得已,左降官。__李崿五杂组,甘咸醋。往复还,乌与兔。不得已,韶光度。__颜真卿五杂组,五色丝。往复还,回文诗。不得已,失喜期。__皎然

进一步分析发现,部分诗句不是以句号结尾的。为了后续任务分析,对感叹号结尾的替换为句号,对没有标点或者多个标点的,去除最后一句,令其句号或问号结尾。但这种语句不多,也可手动处理。

三径何寂寂,主人山上山。亭空檐月在,水落钓矶闲。药院鸡犬静,酒垆苔藓班。知君少机事,当待暮云还
弟兄俱已尽,松柏问何人。闻道茂陵山水好,碧溪流水有桃源。赤城峭壁无人到,丹灶芝田有鹤来。三千宫女露蛾眉,笑煮黄金日月迟。,
浮生共多故,聚宿喜君同。人息时闻磬,灯摇乍有风。霜阶疑水际,夜木似山中。一愿持如意,长来事远公。知

最后从全部诗中提取带有数字的诗句,去除含特殊符号的句子,并将多个句号替换为一个句号。

def MergeTxt(filepath,outfile):
    poemset = set()
    for parent, dirnames, filenames in os.walk(filepath):
        for filepath in filenames:
            txtPath = os.path.join(parent, filepath)
            f = open(txtPath)
            line = f.read()
            line = line.replace('!', '。')        # 将感叹号替换为句号
            line = '。'.join(line.split('。')[:-1])+'。'   # 令句子以最后一个句号结尾
            poem = re.sub("(.*?)", "", line)     # 去除括号里的内容
            poem = re.sub("。卷.*", "。", poem)    # 去除“卷六百五十四”这种
            poemset.add(poem)

    print(len(poemset))

    k = open(outfile, 'w', encoding='utf-8')
    for poem in poemset:
        if poem!='':
            k.write(poem+"\n")
    k.close()

    print("merge finished!")

def extractNumberPoemtry(inputfile,outfile):
    with open(inputfile,'r',encoding="utf-8") as f1, open(outfile,'w') as f2:
        for line in f1:
            if '_' in line:
                continue
            if re.match(".*[一二三四五六七八九十百千万亿].*",line):
                f2.write(line.replace('。。','。'))
  • f.read():每次读取整个文件,它通常将读取到底文件内容放到一个字符串变量中。
  • f.readlines():读取整个文件所有行,保存在一个列表(list)变量中,每行作为一个元素,但读取大文件会比较占内存。

注意
文件在close()之前只能读取一次,不能f.read()之后再f.readlines(),或f.readlines()f.read()之后再这样将输出为空。

扫描二维码关注公众号,回复: 10227679 查看本文章

三、中华古诗数据集处理

首先从json中提取诗词,合并为一个大txt,每行一首诗词。
这个数据集全部为繁体字,所以涉及到繁简转换,这里用到的工具是langconv.pyzh_wiki.py,只需要把这两个文件下载下来,保存到与代码同一目录下即可。工具放在我的GitHub里,地址见后文。
这个数据集同样有一些特殊字符,如{},“”,□等。

莽莽荒茨岸,回回乱石滩。雨寒收市早,风急泊舟难。{宀禹}县兵犹鬭,乾坤网正宽。慇懃嘱龙剑,莫久卧波澜。
遥泉滴滴度更迟,秋夜霜天入竹扉。明月自随山影去,清风长送白云归。(同前书卷六)-1033-。
云中古城郁嵯峨,塞上行吟麦秀歌。感时伤古今如此,报主怀恩奈老何!。
子瞻词里贬眉汉,鲁直诗中返哺僧。□□□□□□针,血写南山□□□。□□□□□□□,□□□□□来似。不曾□□□□□,□□□□□□□。
花榭香红烟景迷,满庭芳草绿萋萋,金铺闲掩绣帘底。YY紫燕一双娇语碎,翠屏十二晚峰齐,梦魂消散醉空闺。
金陵朱世英官长沙,或有画箕踞而坐者号大着肚。旧有赞颂皆鄙语,朱为题小诗其上以易之。其尾云“但将贮酒三千锺,莫话容卿数百辈。”馀爱其语有味,更作此诗以广其意。

处理方法类似:

# 合并同一个文件夹下多个txt
def MergeTxt(filepath,outfile):
    poemset = set()
    for parent, dirnames, filenames in os.walk(filepath):
        for filepath in filenames:
            txtPath = os.path.join(parent, filepath)
            with open(txtPath, encoding='utf-8') as f:
                s = json.load(f)
                for item in s:
                    sentence = ''.join(item["paragraphs"])
                    sentence = Converter('zh-hans').convert(sentence)   # 繁体转简体
                    poem = re.sub("{.*?}", "", sentence)                # 去除{}里的内容
                    poem = re.sub("(.*?)", "", poem)                  # 去除()里的内容
                    poem = re.sub("-.*?。", "", poem)                   # 去除“-143-。”这种内容
                    poem.replace("。。", "。")                           # 将两个句号替换为一个句号
                    poemset.add(poem)
    print(len(poemset))

    k = open(outfile, 'w', encoding='utf-8')
    for poem in poemset:
        if poem != '':
            k.write(poem + "\n")
    k.close()
    print("merge finished!")

# 提取出带数字的诗
def extractNumberPoemtry(inputfile,outfile):
    with open(inputfile,'r',encoding="utf-8") as f1, open(outfile,'w',encoding="utf-8") as f2:
        for line in f1:
            if '□' in line:
                continue
            if re.match(".*[一二三四五六七八九十百千万亿].*",line):
                f2.write(line.replace('。。', '。').replace('!。', '。').replace('!', '。').replace('Y', '').replace('。”。', '。').replace(':“',',').replace('”','').replace('“',','))

注意:replace如果放在MergeTxt()里,速度会慢,放在extractNumberPoemtry()里更快一些。

最后,将两个数据集中提取的带数字的古诗词合并去重即可。

# 把几个数据集的文本合起来
def mergefile(inputfile1,inputfile2,outfile):
    poemset = set()
    with open(inputfile1, 'r', encoding="utf-8") as f1, open(inputfile2, 'r', encoding="utf-8") as f2, open(outfile, 'w', encoding="utf-8") as f3:
        for line1 in f1:
            poemset.add(line1)
        for line2 in f2:
            poemset.add(line2)
        for line in poemset:
            f3.write(line)

注意,txt文件可能需要在文本编辑器里手动转成utf-8编码。

三、自找诗句

这部分为从百度知道等地方找的少部分诗句,需要看是否包含在合并数据集里,如果没有,则手动加入。

with open(mergefile, 'r', encoding="utf-8") as f1,open(finefile,'r',encoding="utf-8") as f2:
    forfindlines = f2.readlines()
    alllines = f1.read()
    print(type(alllines))
    for line in forfindlines:
        if ''.join(line.split('\n')[0]) not in alllines:
            print(''.join(line.split('\n')[0]))

最后得到的带数字的古诗词数据集约为十八万首。
处理脚本和繁简转换工具的全部代码在:https://github.com/vivianLL/PoetryWithNumber

发布了143 篇原创文章 · 获赞 161 · 访问量 29万+

猜你喜欢

转载自blog.csdn.net/vivian_ll/article/details/94578606