Python:按条件重新排列csv行
如果我有几个csv文件,如下所示:
a,1,2,3
type, max, min, avg
b,4,5,6
<empty line>
c,6,7,8
xxx,4,3,2
d,5,6,7
在使用csv读取器读取了上面的csv文件后,我想用xlwt模块把数据导出到一个新的xls文件里,并且要整理得当,这样做:
- 第一行写上表头(这行的第一个项目总是'type')。
- 忽略空行。
- 忽略任何第一个项目是'xxx'的行。
我试过以下代码,但空行还是没有消失。 :(
for filename in glob.glob(p):
(f_path, f_name) = os.path.split(filename)
(f_short_name, f_extension) = os.path.splitext(f_name)
ws = wb.add_sheet(str(f_short_name))
spamReader = csv.reader(open(filename, 'rb'))
for row in spamReader:
pass_count = 0
if 'type' in row[0]:
for col in range(len(row)):
ws.write(0,col,convert(row[col]))
else:
if (((row[0] == 'xxx') or (row[0] == ' ')):
pass_count += 1
pass
else:
for col in range(len(row)):
ws.write(row_count,col,convert(row[col]))
row_count = row_count+1-pass_count
wb.save(q)
编辑:
大家,对我最开始提供的csv数据表示歉意。我的csv数据文件里其实没有空行。空行出现在最终的xls文件中。这个空行正好出现在应该是row[0] - 'type'
的地方。
另外,我还加了一段代码来防止第一行被覆盖。
例如:
a,1,2,3
type, max, min, avg
b,4,5,6
c,6,7,8
xxx,4,3,2
d,5,6,7
输出的xls:
type, max, min, avg
<empty line>
a,1,2,3
b,4,5,6
c,6,7,8
d,5,6,7
在这里,表头被写在了第一行,包含'xxx'的行被忽略了,但第二行出现了空行,这正是输入文件中row[0]='type'
所在的位置。这就是我引入'pass_count'来跳过这一行的原因,但似乎没有解决问题。
2 个回答
如果一行是空的,我觉得这不太可能成立:
row[0] == ' ' # A space?
我本来以为row
会是一个空列表,但也许你的数据里有我不知道的东西。
另外,与其费劲去理清row_count
的逻辑,然后再减去pass_count
,为什么不简单点,每次写入一行Excel的时候就把row_count
加一呢?这样就不需要pass_count
了。
你的“空”行其实并不空。
如果它真的空的话,row
就会是 []
,也就是一个空列表,这样你第一次用到 row[0]
的时候就会出错。但现在没有出错,而且你说它只匹配了一个空格,所以可以推测它里面可能还有其他的空白字符。
为了确保代码的稳健性,特别是处理真正的空行时,应该先检查行是否为空:
if not row: continue
row = [x.strip() for x in row] # remove leading and trailing whitespace from all fields
if not row[0] or row[0] == "xxx": continue
if row[0] == "type":
# code to write headings goes here
else:
# code to write data goes here
row_count += 1 # pass_count is pointless
顺便提一下,你的示例数据在第二行输入中有“type”。这会覆盖输出文件中的第一行,而第二行的输出文件将会是空的!
更新:根据修正后的信息
即使你当前的文件里没有空行,防止完全空行、只有空白的行,以及只包含空白的字段,都是很好的编程习惯,可以使用我建议的那种代码。CSV文件末尾出现空白或空行是很常见的。
我应该提到,你似乎在使用一个老版本的 xlwt
;更新的版本会抛出异常,比如 Attempt to overwrite cell: sheetname=u'x' rowx=0 colx=0
。这个功能是为了防止无意中覆盖数据,可以在每个工作表上单独关闭:workbook.add_sheet(u'Some Sheet Name', cell_overwrite_ok=True)
你在 ws = wb.add_sheet(str(f_short_name))
中使用 str()
是多余的,如果文件名已经是 unicode
对象,这可能会导致异常。