Categorize and calculate something in python
Question: I have following input file

    
    
    O    2.05151  39.51234   0.00000
    O   32.69451   1.48634   8.31300
    O   10.53351  21.63634   7.95400
    O   30.37451  20.74134   0.99700
    Si   8.06451  19.19434  10.21700
    Si  32.03251  42.98634  21.23900
    O    9.69051  19.06934  16.27200
    Si   2.18351  39.67034  11.36500
    Si  31.78351   2.38334   1.42300
    

......

First, I hope to categorize these data based on 4th column, such as [0~1, 1~2,
2~3, ...., max-1 ~ max] and then count the number of 'Si' and 'O' in each of
sections. After that, do some calculation based on those numbers then print
out. Printing format was setted to

    
    
    section1   number_of_Si_in_section1   number_of_O_in_section1   add_two_numbers
    ...
    

with three space devided I tried to use nested for loops, but failed.

    
    
    for i1 in range (total number of lines) 
        for j1 in range (each sections) 
                if (at_name[j1] = 'Si'):
                num_Si = num_Si + 1
                if (at_name[j1] = 'O'):
                num_O = num_O + 1
    

Something like this but I stucked in the middle. I heard that numpy, csvanal
or other function can do this easily, but I have no idea about them.


Answer: You should test small bits of this code line by line in your Python
interpreter. You will see the small mistakes (like you used single equals
instead of double equals to check equality).

Nothing inside the loop depends on `i1`, so it looks like this loop will just
do the same thing again and again. Also, you should use a dictionary (or
better yet, collections.Counter):

    
    
    import collections
    import csv
    
    f = open('myfile.csv','rb')
    reader = csv.reader(f, delimiter='\t')
    
    si_counter = collections.Counter()
    o_counter = collections.Counter()
    
    for line in reader:
        number = int(line[3])
        si_or_o = line[0]
        if si_or_o == 'Si':
            si_counter[number] += 1
        elif si_or_o == 'O':
            o_counter[number] += 1
    

The code is untested and you can improve it.

