【问题标题】:Python writerows only writes the last row of NLTK FreqDist to a csv filePython writerows 仅将 NLTK FreqDist 的最后一行写入 csv 文件
【发布时间】:2020-10-16 17:35:09
【问题描述】:

我一直在编写 Python 代码来使用 Python 列表中包含的单词 (word_list) 来查找文本文档中包含的单词的频率分布。程序计算频率分布,我可以将它们打印到屏幕上,但是当我尝试将频率分布写入 .csv 文件,它只重复写入FreqDist 的最后一行,因为目录中有许多文本文件。我的代码如下

CIK_List = []


for filename in glob.glob(os.path.join(test_path, '*.txt')):

 CIK = re.search(r"\_([0-9]+)\_", filename) # extract the CIK from the filename

 path = nltk.data.find(filename)
 raw = open(path, 'r').read()

 tokens = word_tokenize(raw)
 words = [h.lower() for h in tokens]
 f_dist = nltk.FreqDist([s.lower() for s in words])
 print(f_dist)

 wordcount = collections.Counter()

 CIK_List.append(CIK) 
 with open(file_path, 'w+', newline= '') as csv_file:
  writer = csv.writer(csv_file)
  writer.writerow(["CIK"] + word_list)
  for m in word_list:
    print([CIK.group(1)], [f_dist[m]], end='')

  for val in CIK_List:
     writer.writerows(([val.group(1)] + [f_dist[m] for m in word_list],))

【问题讨论】:

  • 您的代码不完整,因为您没有在任何地方定义CIK_Listfilename 来自哪里?这整个代码块是否在一个循环中,类似于 for filename in ...: ?请编辑您的问题并包含重现问题所需的所有代码。如果您的代码不完整,我们可能会尝试自己填补空白,弄错并为您写一个无益的答案。
  • 我已按要求添加了额外的代码片段。

标签: python csv nltk


【解决方案1】:

问题在于,对于您读取的每个输入文件,您都会创建输出文件并写入

看看代码末尾的以下循环。它有什么作用?

  for val in CIK_List:
     writer.writerows(([val.group(1)] + [f_dist[m] for m in word_list],))

CIK_List 是一个正则表达式匹配列表。对于每个这样的正则表达式匹配,我们写出第一个匹配组(它是文件名的数字部分),然后我们写出 不依赖于val 的东西。因此,当val 遍历正则表达式匹配列表时,您会一次又一次地获得相同的输出。

您还多次打开文件,每个输入文件一次,每次打开文件时,您都会丢弃以前的内容。

您可能想要做的是打开输出文件一次,写出标题行,然后,对于每个输入文件,根据该输入文件的内容将一行写入输出文件:

CIK_List = []
with open(file_path, 'w+', newline= '') as csv_file:
    writer = csv.writer(csv_file)
    writer.writerow(["CIK"] + word_list)

    for filename in glob.glob(os.path.join(test_path, '*.txt')):

        CIK = re.search(r"\_([0-9]+)\_", filename) # extract the CIK from the filename

        path = nltk.data.find(filename)
        raw = open(path, 'r').read()
        
        tokens = word_tokenize(raw)
        words = [h.lower() for h in tokens]
        f_dist = nltk.FreqDist([s.lower() for s in words])
        print(f_dist)
        
        wordcount = collections.Counter()

        CIK_List.append(CIK) 
        for m in word_list:
            print([CIK.group(1)], [f_dist[m]], end='')

        writer.writerow([CIK.group(1)] + [f_dist[m] for m in word_list])

【讨论】:

  • 嗨,卢克,我在一个小数据集上试过这个,它完全可以工作。我已经在一个目录(> 70000)中包含的更大的文本文件样本上运行它,它在我结束程序之前处理了其中的大部分。我明白你关于 open file 语句定位的观点,但是为什么 CIK 的正确分布细节不简单地写在与 CIK 的附加的“val”变量相同的行中,除非重复打开的 .csv 文件重写了吗?
  • @DaleAddison:重复打开 CSV 文件确实会覆盖它,正如我在回答中所写的那样。您可以尝试通过以附加模式打开文件来修改原始代码,方法是将w+ 替换为a+,您会看到您的代码写入文件的所有数据都被覆盖了。不过,只在一个小数据集上运行它:在 70,000 个文件上运行它会生成一个包含超过 20 亿行的 CSV 文件。
猜你喜欢
  • 2021-01-12
  • 2021-06-07
  • 2021-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-26
相关资源
最近更新 更多