0

I've posted a question similar to this, but I'm still having trouble with several things.

I have a list of tuples that looks like this:

[(1, 0.5, 'min'),
 (2, 3, 'NA'),
 (3, 6, 'NA'),
 (4, 40, 'NA'),
 (5, 90, 'NA'),
 (6, 130.8, 'max'),
 (7, 129, 'NA'),
 (8, 111, 'NA'),
 (9, 8, 'NA'),
 (10, 9, 'NA'),
 (11, 0.01, 'min'),
 (12, 9, 'NA'),
 (13, 40, 'NA'),
 (14, 90, 'NA'),
 (15, 130.1, 'max'),
 (16, 112, 'NA'),
 (17, 108, 'NA'),
 (18, 90, 'NA'),
 (19, 77, 'NA'),
 (20, 68, 'NA'),
 (21, 0.9, 'min'),
 (22, 8, 'NA'),
 (23, 40, 'NA'),
 (24, 90, 'NA'),
 (25, 92, 'NA'),
 (26, 130.4, 'max')]

I am running experiments for which each experiment has exactly one "min" and one "max" value. I want to sum up the elements in the first element up to only one "min" and "max." For example, this small dataset has 3 experiments because there are 3 mins and three maxes. The output would look like:

exp = [1+2+3+4+5+6+7+8+9+10, 11+12+13+14+15+16+17+18+19+20, 21+22+23+24+25+26]

I would also like to keep track of the values being added to the list as well so that I also have this output:

exp_values = [[1,2,3,4,5,6,7,8,9,10], [11,12,13,14,15,16,17,18,19, 20], [21, 22, 23, 24, 25, 26]]

I am having trouble trying to get started and only have a general idea so far:

times = []
sum_
for item in tup_list:
    if item[2] != "min":
       sum_ += item[0]
       times.append(sum_)
djennacs
  • 107
  • 1
  • 7
  • Will a `min` entry always appear before its corresponding `max`? Will a `min`/`max` pair always appear together, before another pair begins? – andrew_reece Oct 22 '17 at 03:18
  • Yes, a min entry will always appear before a max. Each pair will have a min/max, so yes, they will appear together in one experiment. – djennacs Oct 22 '17 at 03:19

4 Answers4

0
vals = [(1, 0.5, 'min'),
 (2, 3, 'NA'),
 (3, 6, 'NA'),
 (4, 40, 'NA'),
 (5, 90, 'NA'),
 (6, 130.8, 'max'),
 (7, 129, 'NA'),
 (8, 111, 'NA'),
 (9, 8, 'NA'),
 (10, 9, 'NA'),
 (11, 0.01, 'min'),
 (12, 9, 'NA'),
 (13, 40, 'NA'),
 (14, 90, 'NA'),
 (15, 130.1, 'max'),
 (16, 112, 'NA'),
 (17, 108, 'NA'),
 (18, 90, 'NA'),
 (19, 77, 'NA'),
 (20, 68, 'NA'),
 (21, 0.9, 'min'),
 (22, 8, 'NA'),
 (23, 40, 'NA'),
 (24, 90, 'NA'),
 (25, 92, 'NA'),
 (26, 130.4, 'max')]
it = iter(vals)

out = []
ap = [next(it)[0]]
for e,_,state in it:
    if state == 'min':
        out.append(ap)
        ap = []
    ap += [e]
out.append(ap)
print(out)

Here you go. I don't think python code needs description here.

output:
[[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
 [11, 12, 13, 14, 15, 16, 17, 18, 19, 20],
 [21, 22, 23, 24, 25, 26]]
not_python
  • 904
  • 6
  • 13
0

Here's an easy way to take care of it:

l = []

for i in tup_list:
    if 'min' in i:
        try:
            l.append(temp)
            temp = []
        except:
            temp = []
    temp.append(i[0])

if len(temp) > 0:
    l.append(temp)

print l

[[1,2,3,4,5,6,7,8,9,10], [11,12,13,14,15,16,17,18,19, 20], [21, 22, 23, 24, 25, 26]]

This will get the lists of mins, like in your variable exp_values. To get the sums of these values, just sum the lists:

sums = list(map(sum, l))

print sums

[55, 155, 141]
Evan Nowak
  • 895
  • 4
  • 8
  • thanks, this looks really nice and clean! is the variable temp supposed to be first defined outside the loop, though? like... temp = []? – djennacs Oct 22 '17 at 03:43
  • No it isn't @djennacs, I did it like this and used `try` and `except` to avoid checking for the first "min". – Evan Nowak Oct 22 '17 at 03:47
  • oh...that makes sense. it just didn't run on my machine saying temp was not defined when you first append it to the list, which is why I asked. – djennacs Oct 22 '17 at 03:49
  • Using try and except means it doesn't have to be defined first. You won't get that error if you type it correctly. – Evan Nowak Oct 22 '17 at 03:56
0

Here's a solution which keeps track of the indices that are a part of each experiment, and then computes the sum at the end.

tup_list = [(1, 0.5, 'min'),
 (2, 3, 'NA'),
 (3, 6, 'NA'),
 (4, 40, 'NA'),
 (5, 90, 'NA'),
 (6, 130.8, 'max'),
 (7, 129, 'NA'),
 (8, 111, 'NA'),
 (9, 8, 'NA'),
 (10, 9, 'NA'),
 (11, 0.01, 'min'),
 (12, 9, 'NA'),
 (13, 40, 'NA'),
 (14, 90, 'NA'),
 (15, 130.1, 'max'),
 (16, 112, 'NA'),
 (17, 108, 'NA'),
 (18, 90, 'NA'),
 (19, 77, 'NA'),
 (20, 68, 'NA'),
 (21, 0.9, 'min'),
 (22, 8, 'NA'),
 (23, 40, 'NA'),
 (24, 90, 'NA'),
 (25, 92, 'NA'),
 (26, 130.4, 'max')]

all_experiment_data = []
current_experiment_data = []
for item in tup_list:
    index, _, point_type = item
    if point_type=="min" and current_experiment_data: #Starting a new experiment, flush the old one
        all_experiment_data.append(current_experiment_data)
        current_experiment_data = []
    current_experiment_data.append(index)

#Flush the last experiment
all_experiment_data.append(current_experiment_data)

all_experiment_sums = [sum(experiment_indices) for experiment_indices in 
all_experiment_data]

print("Indices in each of the experiments:")
print(all_experiment_data)
print("Sums of indices for experiments:")
print(all_experiment_sums)

This produces:

Indices in each of the experiments:
[[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [11, 12, 13, 14, 15, 16, 17, 18, 19, 20], [21, 22, 23, 24, 25, 26]]
Sums of indices for experiments:
[55, 155, 141]
augray
  • 3,043
  • 1
  • 17
  • 30
0

For this sequence, you need to keep track of how many times you come across min and max. Once a new min comes in, it is beginning of new sequence. So I used inSeq as tracker for the sequence. Let me know if it helps:

times = []
sum_ = 0
inSeq = 0
for item in tup_list:
    if(item[2] == 'min' or item[2] == 'max'):
        inSeq += 1
    if(inSeq == 3): #start of new sequence when it hits new min
        times.append(sum_)
        sum_ = item[0] 
        inSeq = 1 
    else:  
        sum_ += item[0]   
v.coder
  • 1,822
  • 2
  • 15
  • 24