【问题标题】:How do I iterate through columns using a for loop and the csv library in Python?如何使用 for 循环和 Python 中的 csv 库遍历列?
【发布时间】:2015-03-27 23:12:08
【问题描述】:

我是一个非常新手的 Python 用户,试图对 .csv 文件中的数据列求和。我找到了其他真正帮助我入门的答案(例如herehere)。

但是,我的问题是我想遍历我的文件以获取所有列的总和。

我的格式化数据如下所示:

    z   y   x   w   v   u
a   0   8   7   6   0   5
b   0   0   5   4   0   3
c   0   2   3   4   0   3
d   0   6   7   8   0   9

或者像这样的 .csv 格式:

,z,y,x,w,v,u
a,0,8,7,6,0,5
b,0,0,5,4,0,3
c,0,2,3,4,0,3
d,0,6,7,8,0,9

目前,我只是想让迭代工作。我会担心以后的求和。这是我的代码:

import csv
data = file("test.csv", "r")
headerrow = data.next()
headerrow = headerrow.strip().split(",")
end = len(headerrow)
for i in range (1, end):
    for row in csv.reader(data):
        print row[i]

这是我得到的:

>>> 
0
0
0
0
>>> 

因此,它会为每一行打印索引 1 处的值,但不会继续通过其他索引。

我在这里遗漏了什么明显的东西?

更新:

根据非常有用的建议和解释,我现在有了这个:

import csv
with open("test.csv") as data:
    headerrow = next(data)
    delim = "," if "," == headerrow[0] else " "
    headerrow = filter(None, headerrow.rstrip().split(delim))
    reader = csv.reader(data, delimiter=delim, skipinitialspace=True)
    zipped = zip(*reader)
    print zipped
    strings = next(zipped)
    print ([sum(map(int,col)) for col in zipped])

这会返回一个错误:

Traceback (most recent call last):
  File "C:\Users\the hexarch\Desktop\remove_total_absences_test.py", line 9,     in <module>
    strings = next(zipped)
TypeError: list object is not an iterator

我不明白这个...?对不起!

【问题讨论】:

  • 只使用 csv 模块,不要预解析任何东西。您正在改变文件对象的状态。

标签: python csv


【解决方案1】:
import csv
with  open('in.csv')as f:
    head = next(f)
    # decide delimiter by what is in header 
    delim = "," if "," ==  head[0] else " "
    # need to filter empty strings 
    head = filter(None, head.rstrip().split(delim))
    # skipinitialspace must be set as you have two spaces delimited
    reader = csv.reader(f,delimiter=delim, skipinitialspace=True)
    # transpose rows
    zipped = zip(*reader)
    # skip first column
    strings = next(zipped)
    # sum each column
    print([sum(map(int,col)) for col in zipped])

[0, 16, 22, 22, 0, 20]

要创建与列总和匹配的 dict,您可以这样做:

print(dict(zip(list(head), (sum(map(int,col)) for col in zipped))))

哪个输出:

{'u': 20, 'w': 22, 'x': 22, 'z': 0, 'y': 16, 'v': 0}

以上所有内容我都使用了python3,如果您使用的是python2,请替换为:

zip -> itertools.izip
filter -> itertools.izip
map -> itertools.imap

Python 2 代码:

import csv
from itertools import izip, imap, ifilter
with  open('in.csv')as f:
    head = next(f)
    # decide delimiter by what is in header
    delim = "," if "," ==  head[0] else " "
    # need to filter empty strings
    head = ifilter(None, head.rstrip().split(delim))
    # skipinitialspace must be set as you have two spaces delimited
    reader = csv.reader(f,delimiter=delim, skipinitialspace=True)
    # transpose rows
    zipped = izip(*reader)
    # skip first column
    strings = next(zipped)
    # sum each column
    print([sum(imap(int,col)) for col in zipped])

输出:

[0, 16, 22, 22, 0, 20]

如果你做了大量此类工作,那么 pandas 尤其是 pandas.read_csv 可能会很有用,下面是一个非常基本的示例,希望一些 pandas 大师可以添加:

import  pandas as pd

df = pd.read_csv("in.csv")
print(df.sum())
Unnamed: 0    abcd
z                0
y               16
x               22
w               22
v                0
u               20
dtype: object

【讨论】:

  • 这很有帮助,尤其是与上面来自 jkdc 的 cmets 一起使用。但是,我收到以下错误Traceback (most recent call last): File "C:\Users\the hexarch\Desktop\remove_total_absences_test.py", line 9, in &lt;module&gt; strings = next(zipped) TypeError: list object is not an iterator
  • @LaurasianDisjunction。我只是在编辑。我正在使用 python3,要使用 python2 复制上面的代码,请使用 itertools 来编辑我的答案
  • @LaurasianDisjunction,添加了等效的python2代码
  • 哦,哈利路亚,星期五快乐,赞美天上的天使,你愿意嫁给我吗?!我现在可以生成一些数据并继续我的生活。这正是我想要的!
  • @LaurasianDisjunction.lol 不用担心,感谢您的建议,但我已发誓不再与互联网上的人结婚 ;)
【解决方案2】:

你可以使用numpy:

import csv
import numpy as np
with open("test.csv") as f:
    r = csv.reader(f, delimiter=",")
    # For space format: r = csv.reader(f, delimiter=" ", skipinitialspace=True)
    # Thanks to Padraic Cunningham ^^
    next(r) # Skip header row
    sums = sum((np.array(map(int, row[1:])) for row in r))

结果:

>>> sums
array([ 0, 16, 22, 22,  0, 20])

【讨论】:

  • 第一个例子会失败
  • @PadraicCunningham 为什么要这么迂腐?我不认为分隔符检测是问题:)
  • 当他明确表示他只是想让迭代工作时,他应该如何使用 numpy。
  • 我认为这实际上是问题的很大一部分,有代码可以使用通过的任何一个,第一个示例无法使用 csv 开箱即用。需要跳过初始空格
  • @Jkdc 其他人也可以使用答案。
【解决方案3】:

这可能会澄清一些究竟发生了什么......看起来你有点过于复杂了。这是一个非常简单的 Python,并非旨在直接或最终解决您的问题,但更有助于了解正在发生的事情。

import csv 

sumthree = 0

with open('test.csv', 'rb') as f:    # Open the file (always use binary 'rb' mode for CSV files)
    header = next(f)        # Extract the header line from the file
    csvr = csv.reader(f)    # Create a CSV object with the rest of the file
    for row in csvr:
        print row           # Now loop over the file and print each row

        sumthree += int(row[2])

    print sumthree

此时每个row 都将打印为一个列表,例如['a','0','8','7','6','0','5']

因此,通过该循环的每次迭代,我们都会逐行向下移动。 row[0] 将是第一列,row[1] 将是第二列,依此类推。如果您想对文件的第三列求和,您可以使用 sumthree += int(row[2])。最后我们print sumthree 并查看第三列中所有数字的总和。

【讨论】:

    猜你喜欢
    • 2019-11-11
    • 2021-03-04
    • 1970-01-01
    • 2019-01-15
    • 1970-01-01
    • 2017-01-23
    • 2021-04-01
    • 1970-01-01
    相关资源
    最近更新 更多