How can I iterate through columns using a for loop and csv library in Python?

advertisements

I am an extremely novice Python user trying to sum columns of data in a .csv file. I found other answers that really helped me to get started (here and here, for example).

However, my problem is that I want to loop over my file to get sums for all columns.

My formatted data look like this:

    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

Or like this in .csv format:

,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

For right now, I am just trying to get the iteration to work. I will worry about the summing later. Here's my code:

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]

Here is what I get:

>>>
0
0
0
0
>>>

So, it prints the values at index 1 for each row, but does not continue through the other indices.

What obvious thing am I missing here?

Update:

Following the very helpful suggestions and explanations, I now have this:

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])

This returns an error:

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

I do not understand this...? Sorry!


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]

To create a dict matching headers to colunm sums you can so something like:

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

which outputs:

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

I used python3 for all of the above, if you are using python2 replace with:

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

Python 2 code:

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])

Output:

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

If you are doing a lot of this kind of work then pandas especially pandas.read_csv may be useful, below is a very basic example, some pandas guru may hopefully add to it:

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