Python:按条件重新排列csv行

1 投票
2 回答
528 浏览
提问于 2025-04-16 17:57

如果我有几个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 个回答

3

如果一行是空的,我觉得这不太可能成立:

row[0] == ' '  # A space?

我本来以为row会是一个空列表,但也许你的数据里有我不知道的东西。

另外,与其费劲去理清row_count的逻辑,然后再减去pass_count,为什么不简单点,每次写入一行Excel的时候就把row_count加一呢?这样就不需要pass_count了。

3

你的“空”行其实并不空。

如果它真的空的话,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 对象,这可能会导致异常。

撰写回答