Python - csv writer 按列而不是按行写入
Posted
技术标签:
【中文标题】Python - csv writer 按列而不是按行写入【英文标题】:Python - csv writer write by column, not row 【发布时间】:2015-04-24 20:44:04 【问题描述】:我正在处理一系列文本文件,我想从中保留一些变量。我试图将这些变量保存在 csv 文件中。每个文本文件将从此 csv 文件中获取 1 行和 N 列。我可以有 1000 个或更多文件,这将导致 csv 文件具有 1000 行和 N 列(N 可以是 10 或更多或更少)。我正在尝试使用以下代码
res=[variable1, variable2, variable3, ..., variableN]
csvfile = "summary.csv"
with open(csvfile, "w") as output:
writer = csv.writer(output, lineterminator='\n')
writer.writerows(res)
问题是它在每一行中写入一个值,然后移动到下一个变量的下一行。而我希望每个文本文件的所有变量占据 1 行(和 N 列)。我应该如何更改我的代码才能使其正常工作?
编辑
import re
import collections
from collections import Counter
import csv
import sys
wanted1 = re.findall('\w+', open('words1.csv').read().lower())
wanted2 = re.findall('\w+', open('words2.csv').read().lower())
for f in sys.argv[1:]:
words = re.findall('\w+', open('f').read().lower())
cnt = Counter()
cnt1 = 0
cnt2 = 0
cntWords = 0
for word in words:
cntWords += 1
if word in wanted1:
cnt[word] += 1
cnt1 += 1
if word in wanted2:
cnt[word] += 1
cnt2 += 1
print cnt1, cnt2, cntWords
res=[cnt1, cnt2, cntWords]
csvfile = "summary.csv"
with open(csvfile, "w") as output:
writer = csv.writer(output, lineterminator='\n')
writer.writerow(res)
在这种情况下,这些变量中的每一个都是一个数字。我还想添加一些包含字符串内容的变量。每个文本文件将占据 1 行。每个变量将占据一个单元格。
例如,cnt1 的值可能为 10000,cnt2 的值可能为 2000,cntWords 的值可能为 30000 等等。
我尝试更改代码以处理文件夹中的所有 .txt 文件,但现在出现错误
File "countWords.py", line 29
writer = csv.writer(output, lineterminator='\n')
^
IndentationError: unindent does not match any outer indentation level
编辑 2:Output.csv 应该是这样的
Column 1 Column 2 Column 3
Row 1: Cnt1 Cnt2 CntWords (all row 1 values should be derived from file1.txt)
Row 2: Cnt1 Cnt2 CntWords (all row 2 values should be derived from file2.txt)
Row 3: Cnt1 Cnt2 CntWords (all row 3 values should be derived from file3.txt)
Row 4: Cnt1 Cnt2 CntWords (all row 4 values should be derived from file4.txt)
Row 5: Cnt1 Cnt2 CntWords (all row 5 values should be derived from file5.txt)
Row 6: Cnt1 Cnt2 CntWords (all row 6 values should be derived from file6.txt)
Cnt1 表示 Cnt1 的值,Cnt2 表示 Cnt2 的值,CntWords 表示 CntWords 的值(这些将是数字)
Column 1 Column 2 Column 3
Row 1: 5000 3000 10000 (all row 1 values should be derived from file1.txt)
Row 2: 510 420 1423 (all row 2 values should be derived from file2.txt)
这意味着输入的是2个文本文件,第一个文本文件有单词表1的5000个单词,单词表2的3000个单词,总共10000个单词,而第二个文本文件有单词表1的510个单词,420词表2的词,共1423个词。
【问题讨论】:
我不清楚variable1
等中包含哪些类型的数据。我的回答在这里解决了两种可能性,但如果您更新您的问题以向我们提供示例输入数据,将会很有帮助和预期的输出,以及你现在得到的错误输出。这不一定是真实数据,只是一个示例,向我们展示正在发生的事情以及您想要什么。
好的,请稍候,我会尽快更新我的答案。
刚刚编辑了我最初的帖子。谢谢
看,你在这里做的是完全不同的事情。您将 Counter
对象写入 CSV 的事实完全改变了您需要做的事情。每个计数器的预期输出是什么?
抱歉没有正确解释。对于文件循环内的每个文本文件,计数器应设置为零。我有两个单词列表,我计算每个文本文件中属于该单词列表的单词数。然后我还计算每个文本文件中的总字数。我想把这些写在一个摘要 csv 文件中(每个文件应该占据一行 N 列,N 是我要保留的变量数)
【参考方案1】:
如果您只想将 3 个计数器写入 CSV 文件,那么只需在循环中写入 CSV 文件。在循环之外创建 CSV 写入器,并在处理文件时向其中写入行:
find_words = re.compile(r'\w+').findall
# create *sets* for faster membership tests
wanted1 = set(find_words(open('words1.csv').read().lower()))
wanted2 = set(find_words(open('words2.csv').read().lower()))
csvfile = "summary.csv"
with open(csvfile, "wb") as output:
writer = csv.writer(output)
for f in sys.argv[1:]:
cnt1 = cnt2 = cntWords = 0
with open(f) as inputfile:
for line in inputfile:
for word in find_words(line.lower()):
cntWords += 1
if word in wanted1:
cnt1 += 1
if word in wanted2:
cnt2 += 1
writer.writerow([cnt1, cnt2, cntWords])
我还将您的 wanted*
列表替换为用于快速成员资格测试的集合(而不是每次在恒定时间内找到单词时扫描整个列表),并改为逐行扫描输入文件以避免破坏记忆。
【讨论】:
这段代码给了我以下错误:文件“countWordsLM.py”,第 26 行 cntWords += 1 ^ IndentationError: expected an indented block 。另外,最后一行是否缺少括号或某事? 看起来不错(并且您正在做的优化速度更快)。问题是它将所有内容放在一列中,550,66,553705,而这些数字应该放在单独的列中..有什么想法可以改变吗? @adrCoder:那些是单独的列,用逗号分隔列。如果您需要不同的列分隔符,请告诉csv.writer()
对象。
你不应该把文件的字数降低或……吗?有些数字低于我之前得到的数字,您确定您从列表和文件中正确计算了单词吗? (单词可能很小或带有大写字母或其他任何内容,您是否正在检查这些?也许 open(f) 中的单词也应该归结为 .lower() ?
@adrCoder:我错过了str.lower()
电话,是的。【参考方案2】:
第 18 行的缩进错误,应该是这样的
csvfile = "summary.csv"
with open(csvfile, "w") as output:
writer = csv.writer(output, lineterminator='\n')
for f in sys.argv[1:]:
words = re.findall('\w+', open('f').read().lower())
cnt1, cnt2 = 0, 0
cntWords = len(words)
for word in words:
if word in wanted1:
cnt1 += 1
if word in wanted2:
cnt2 += 1
print cnt1, cnt2, cntWords
res = [cnt1, cnt2, cntWords]
writer.writerow(res)
附:计数器用法见example
【讨论】:
缩进问题不是实际问题。 @MartijnPieters 为什么不呢?他想在一个 csv raw 中写入一个文件。 对,这个问题一开始是完全不同的;很可能唯一剩下的就是缩进错误。 我想指出,以这种方式计算单词也会计算单词重复 你好,我认为它需要是 open(f).read().lower()),open('f').read().lower()) 给我一个错误 Traceback (最近一次通话最后一次):文件“countWordsLM.py”,第 14 行,在以上是关于Python - csv writer 按列而不是按行写入的主要内容,如果未能解决你的问题,请参考以下文章
使用 CRLF 而不是 LF 的 CSV Writer (Python)