3

VERY new to Python, don't mean to insult anyones intelligence.

I have a large list, contains a series of ids and related values, extremely shortened version looks like so:

large = [('550111', [(4, 5, 8), (6, -4, -6)]), ('222211', [(2, -4, 5), (1, 15, -4)])]

I have code like so which exports an ideal format to Excel, however without the desired modifications:

import csv
with open("out1.csv", "wb") as fp: 
 writer = csv.writer(fp, delimiter=",")     
for entry in large:        
 writer.writerow([entry[0]])         
for line in entry[1]:             
 writer.writerow(line)        
 writer.writerow([])

Output from this to Excel (every value with its own separate cell - 5501 being in A1, 4 in A2, 5 in B2, 8 in C2... the first space would be in A4 etc.) looks like:

550111 
4,5,8 
6,-4,-6  
<space here - dont know how to put them in>
222211 
2,4,-5 
1,-15, 4 
 <space here - dont know how to put them in>

Which is perfect, however I also wish to produce the absolute max of the values. This is where I need help. I do not know how to write the absolute max function into exporting code as I keep getting an error saying I cannot apply a function to a list.

Also I need to insert a numerical sequence ranging from 1 to 8904 at the very end.

Desired form after being exported to Excel - has absolute max .i.e neglectinf '-' signs and a sorted absolute max

550111 
4,5,8 
6,-4,-6
'space here'
'Max:'
6, 5, 8
'Sorted max'
8, 6, 5
'space here'     
222211 
2,4,-5 
1,-15,4
'space here'
'Max:'
2, 15, 5
'Sorted max:' 
15, 5, 2
'space here'
1, 2, 3, ........, 8904 

Sorry if question is annoying/rookie/trivial. Help really appreciated.

user1532369
  • 179
  • 1
  • 1
  • 10
  • @dm03514: I'm pretty sure by "own Excel rectangle thing to itself" the OP simply means "separate cell". – DSM Aug 10 '12 at 15:48
  • "own Excel rectangle thing to itself" - I would probably not have been able to understand that - thanks for the translation. – Stepan1010 Aug 10 '12 at 16:22

3 Answers3

2

I think the following code fragment can help you in getting the max and sorted max values. Sorry can't help you in putting them in excel though

for entry in large:
    max_list=[]
    for z in zip(*entry[1]): 
        max_list.append(max(z))
    print max_list
    max_list.sort(reverse=True)
    print max_list

[6, 5, 8]
[8, 6, 5]
[2, 15, 5]
[15, 5, 2]

Baically for every entry in large dataset, you have to process entry1 list (which is a list of tuples). Using zip you can 'zip' through multiple data-structures simultaneously.

zip(*entry[1])

This line basically unrolls all the tuples in your list and loops through them concurrently. Thus during first iteration, all the first elements of all the tuples are selected and stored as a tuple.

Using max function, you can get the maximum value and store it in a separate list (A new list for each entry). Then you can sort that list in reverse to get what you want

EDIT

Just noticed you need the absolute max. So the code fragment gets modified as

for entry in large: 
    max_list=[]
    for z in zip(*entry[1]): 
        max_list.append(max(abs(t) for t in z))
    print "Absolute max",max_list
    max_list.sort(reverse=True)
    print "Sorted Absolute Max",max_list

Input

large = [('5501', [(4, -5, 8), (6, -4, -6)]), ('2222', [(2, -4, 5), (1, -15, -4)])]

Output

Absolute max [6, 5, 8]
Sorted Absolute Max [8, 6, 5]
Absolute max [2, 15, 5]
Sorted Absolute Max [15, 5, 2]

EDIT2

Since you asked about zip and editted code, I'll try to explain this.

zip() is an in-built python function which helps you in iterating over multiple iterables (lists,tuples and any other thing you can iterate over) parallely.

>>> a=[1,2,3,]
>>> b=[4,5,6,]
>>> zip(a,b)
[(1, 4), (2, 5), (3, 6)]

The i-th tuple of the result is a collection of i-th elements of the input lists

In your case entry[1] is the list of tuples you want to 'zip' over, but zip only works if we give it multiple lists not a single list of lists!

This is where * operator comes in handy. It will splat you list of lists into multiple lists.

>>> def printme(*a): 
...     for i in a: 
...         print i
... 
>>> m=[(1,2,),(3,4,),(5,6,),]
>>> printme(m)
[(1, 2), (3, 4), (5, 6)]
>>> printme(*m)
(1, 2)
(3, 4)
(5, 6)

And if you want to find the maximum value in a list, you can use the in-built max() function.

Now we have all the theoretical elements needed to solve your problem. Lets say

>>> entry=('5501', [(4, -5, 8), (6, -4, -6)])
>>> entry[1]
[(4, -5, 8), (6, -4, -6)]

What you want to do is zip over these tuples so that all the first elements form a separate tuple, all the second elements form a separate tuple and so on.

>>> zip(entry[1])
[((4, -5, 8),), ((6, -4, -6),)]

No Good!!! Lets use the *

>>> zip(*entry[1])
[(4, 6), (-5, -4), (8, -6)]

Perfect! Now for each tuple in the list, all we need to do is do a max() to find out the maximum value and store it somewhere.

>>> for z in zip(*entry[1]): 
...     print "I have",z
...     print "max is",max(z)
... 
I have (4, 6)
max is 6
I have (-5, -4)
max is -4
I have (8, -6)
max is 8

So if we initialize an empty list and append the maximum values to it, we get the maximum value list! Hence the first code that I wrote

max_list=[]
for z in zip(*entry[1]): 
    max_list.append(max(z))
print max_list

Gives us

[6, -4, 8]

To sort the max_list itself, we use sort method of the lists

max_list.sort(reverse=True)
print max_list

Gives us

[8, 6, -4]

But we need the absolute max of the values.

In the above code fragment, z, holds the values. So we need a way to convert those values into their absolute. The in-built abs(), only works for a number so we need to apply it to each element of z

>>> for z in zip(*entry[1]): 
...     print z
...     new_z = []
...     for i in z: 
...         new_z.append(abs(i))
...     print new_z
... 
(4, 6)
[4, 6]
(-5, -4)
[5, 4]
(8, -6)
[8, 6]

Or we can be pythonic and shorten it to

>>> for z in zip(*entry[1]): 
...     print z
...     new_z=[abs(i) for i in z]
...     print new_z
... 
(4, 6)
[4, 6]
(-5, -4)
[5, 4]
(8, -6)
[8, 6]

But we also need the maximum value of new_z. That is easy max(new_z). Our code now is

max_list=[]
for z in zip(*entry[1]): 
    new_z=[abs(i) for i in z]
    max_list.append(max(new_z))       
print max_list

Which gives us

[6, 5, 8]

This is what we want. But wait, we can still shorten the code

new_z=[abs(i) for i in z]
max_list.append(max(new_z)) 

Can be converted to a single line

max_list.append(max( abs(t) for t in z ))

Which brings us to the final code

for entry in large: 
    max_list=[]
    for z in zip(*entry[1]): 
        max_list.append(max(abs(t) for t in z))
    print "Absolute max",max_list
    max_list.sort(reverse=True)
    print "Sorted Absolute Max",max_list

Hope this helps

Community
  • 1
  • 1
RedBaron
  • 4,717
  • 5
  • 41
  • 65
0

Not sure if this is a python or excel question but in excel: the function for the "Maximum of absolute values within a range in one step" is:

=MAX(INDEX(ABS(F17:F22),0,1))

I'm not familiar with python, but I am sure there is a way to insert a formula into a cell - so I will leave that up to you or someone else to answer. Good Luck.

sources: http://www.mrexcel.com/forum/showthread.php?47999-Maximum-of-absolute-values-within-a-range-in-one-step

https://groups.google.com/forum/?fromgroups#!topic/python-excel/bRDXSVWstxo%5B1-25%5D

Stepan1010
  • 3,136
  • 1
  • 16
  • 21
0

With the xlwt module you can export directly to binary Excel file format instead of CSV in order to make use of dynamic Excel formulas.

This is fine for spreadsheets bellow 65k lines (limit of the ancient Excel format used by xlwt).

[update]

I'm not sure I understood what you want. If you want to calculate max, just do that.

import csv
with open("out1.csv", "wb") as fp: 
    writer = csv.writer(fp, delimiter=",")
    for entry, data in large:
        values = []
        writer.writerow([entry])
        for line in data:             
            writer.writerow(line)
            values.extend(line)
        writer.writerow([])
        writer.writerow(['Sorted Max'])
        writer.writerow(sorted(values, reverse=True)[:3])
        writer.writerow([])

[update]

Long strings of comments are not welcome here, so I asked to move it to the chat room. Be aware that I have my own work to do and may take some minutes to answer. Remember, I'm volunteering to help you... If you deserve my help I deserve your patience.

By "abs max" you mean the top 3 integers in the same order they occur in the data set?

top3 = sorted(values, reverse=True)[:3]
absmax = filter(lambda x: x in top3, values)

By "at the very end" you mean a a few columns at the right? Using the xlwt module you has precise control over line/column - but using the csv module you will have to fill the columns by yourself. Please adapt the following example to your use case:

c = 1
for a in range(10):
    writer.writerow([a, ' ', ' ', c])
    c += 1
    writer.writerow([a+1, a+2, a+3, c])
    c += 1
    writer.writerow([' ', ' ', ' ', c])
    c += 1

Result:

0, , ,1
1,2,3,2
 , , ,3
1, , ,4
2,3,4,5
 , , ,6
2, , ,7
3,4,5,8
 , , ,9
...
Paulo Scardine
  • 73,447
  • 11
  • 124
  • 153