2

Here's part of my Python code, I'm trying to find the 4 consecutive values in spec which yields the maximum sum, and then find the weighted average value of the corresponding 4 keys:

spec = {1.5:8, 1.3:9, 4.3:7, 3.2:3, 5.3:5, 4:1, 5.2:6, 4.2:4, 2.5:9} 
k = 4
consecutive_elements = zip(*(islice(spec.values(), x, None) for x in range(k)))
max(map(sum, consecutive_elements)) # The maximum sum.
Wavg = np.average(list(???.keys()), weights=list(???.values())) # The weighted average

I'm not sure how I can access the 4 keys. In this case, they should be 1.5, 1.3, 4.3, 3.2 since the sum of their values is 27 (the maximum). Which tools should I use?

Mad Physicist
  • 107,652
  • 25
  • 181
  • 264
ZR-
  • 809
  • 1
  • 4
  • 12

1 Answers1

3

Your data is not really a mapping as much as a pair of sequences with corresponding elements. I would recommend visualizing it as such:

keys = list(spec.keys())
vals = list(spec.keys())

From here it should be pretty clear how to do using something like implementing argmax in Python:

consecutive_elements = zip(*(islice(spec.values(), x, None) for x in range(k)))
idx = max(enumerate(map(sum, consecutive_elements)), key=itemgetter(1))[0] # The maximum sum.
Wavg = sum(a * b for a, b in zip(keys[idx:idx + k], vals[idx:idx + k])) / sum(vals[idx:idx + k])

That being said, if you're using numpy anyway, I'd say commit to it:

keys = np.fromiter(spec.keys(), float, count=len(spec))
vals = np.fromiter(spec.values(), float, count=len(spec))

idx = np.convolve(vals, np.ones(k), 'valid').argmax()
Wavg = np.average(keys[idx:idx + k], weights=vals[idx:idx + k])

The results from both versions are exactly identical:

2.348148148148148
Mad Physicist
  • 107,652
  • 25
  • 181
  • 264