使用Python读取和提取CSV文件列

1 投票
1 回答
5874 浏览
提问于 2025-04-16 01:07

我有以下代码...

reader=csv.DictReader(open("test1.csv","r"))
allrows = list(reader)

keepcols = [c for c in allrows[0] if all(r[c] != '0' for r in allrows)]

print keepcols
writer=csv.DictWriter(open("output1.csv","w"),fieldnames='keepcols',extrasaction='ignore')
writer.writerows(allrows)

我有一个CSV文件,大约有45列。
第一列是一些名字。
除了第一列,其他列只有0和1...
当然,整个表格还有一些标题。
我想从这个CSV文件中读取列,只提取那些包含1的列。
问题是输出文件是空的,尽管表格中确实有几列是1。

有人能帮帮我吗.... :( 我现在卡住了..

Title    3003_contact    3003_backbone   3003_sidechain  3003_polar  3003_hydrophobic    3003_acceptor   3003_donor  3003_aromatic
l1  1   1   0   1   1   0   0   0
l1  1   0   1   0   0   0   1   0
l1  1   0   0   0   0   0   0   0
l1  1   0   0   0   1   0   0   1
l1  1   0   0   0   0   0   0   0
l2  1   0   0   0   1   0   0   0
l2  1   0   0   0   0   1   0   0
l3  1   0   0   0   0   0   0   0
l3  1   0   0   0   0   0   1   0
l3  1   0   0   0   0   0   0   1
l3  1   0   0   0   0   0   0   0
l3  1   0   0   0   0   0   0   0
l4  1   0   0   0   0   0   0   0
l4  1   0   0   0   0   0   0   0
l4  1   0   0   0   0   0   0   0

它只返回第一列... 我试着把'keepcols'改成keepcols... 然后我得到的是第二列在前,第一列在后作为输出。

1 个回答

4

编辑:如果输入文件是一个用逗号分隔的值文件,为了保持键的顺序,应该使用 reader.fieldnames,而不是 allrows[0] 中的键。

所以解决方案是:

keepcols = [c for c in reader.fieldnames if any(r[c] != '0' for r in allrows)]

上面提到的输入文件看起来是用空格分隔的列。在这种情况下,我觉得 csv 不是解析它的合适工具。相反,你可以使用 split

import csv
with open("test1.csv","r") as f:
    fields=next(f).split()
    # print(fields)
    allrows=[]
    for line in f:
        line=line.split()
        row=dict(zip(fields,line))
        allrows.append(row)
        # print(row)
    keepcols = [c for c in fields if any(row[c] != '0' for row in allrows)]
    print keepcols
    writer=csv.DictWriter(open("output1.csv","w"),fieldnames=keepcols,extrasaction='ignore')
    writer.writerows(allrows)

编辑2:列的顺序变化的原因是因为 for c in allrows[0] 返回 allrows[0] 的键时顺序是不确定的。默认情况下,dict 的键是没有顺序的。上面的代码通过将 fields 定义为一个列表,而不是 dict,来解决这个问题。

原始答案:fieldnames='keepcols' 改为 fieldnames=keepcols

fieldnames 需要是一个键的序列,比如 ['fieldA','fieldB',...]

在 Python 中需要注意的一个潜在问题是字符串也是序列。当你遍历一个字符串时,你得到的是字符串中的字符。所以当你写 fieldnames='keepcols' 时,你实际上是把 fieldnames 设置为字符序列 ['k','e','e','p','c','o','l','s']。你不会得到错误,因为这是一个有效的键序列。但是你的字典列表 allrows 并没有这些键。writer.writerows 会无视这个问题,因为 extrasaction='ignore'

撰写回答