-1

I have the following lists:

a= [1,2,3,4,5,6,7,8,9,10,11,12]
wts= [0.055555556,0.055555556,0.055555556,0.055555556,0.055555556,0.055555556,0.055555556,0.055555556,0.055555556,0.10,0.10,0.30]

The Desired result is

result = [8.2,7.76,7.848,7.9504,8.179253333,8.420282667,8.628383467,8.790601973,8.894139057,8.930025594,8.891166196,8.770706404]

The result is the moving window sum product of list 'a' and list 'wts'.

For example Result 8.2 is obtained by code

sum(map(lambda xi, yi: xi * yi,x,wt))

The result is obtained by new window of a obtained by appending 8.2 to list 'a'.

The new list a should be where the result from above result is appended.

a = [1,2,3,4,5,6,7,8,9,10,11,12,8.2]

Now to calculate the next value of result list i.e result[1] = 7.76, it should be the sumproduct of

a = [2,3,4,5,6,7,8,9,10,11,12,8.2] and 
wts = [0.055555556,0.055555556,0.055555556,0.055555556,0.055555556,0.055555556,0.055555556,0.055555556,0.055555556,0.10,0.10,0.30]

The 'wts' list is fixed and only list 'a' would be moving window, with the new result getting appended to a.Any python script to achieve this would be of great help here.

Based on the Below,I apply the below function to a dataframe. Could you please throw some light as to how I apply this function to a dataframe based on multiple groups(based on Groupby).

def wma(Curr,wts):
    Curr.values.tolist()
    wts.values.tolist()
    len_list = len(Curr)
    # Create a fixed sized queue
    q = deque(maxlen=len_list)
    # Add list a to q
    q.extend(Curr)
    i = 0
    result = []
    while i < len(a):
        val = sum([x*y for x, y in zip(q, wts)])
        q.append(val)
        result.append(float(round(val, 2)))
        i += 1
    return result

For example I have a dataframe with 5 columns namely (Column A, Column B, Column C, Weights, Current). I apply the above function using the below code

s1 = s1.groupby(['Column A', 'Column B', 'Column C']).apply(wma(df['Current'],df['Weights']))

I get the following Error : TypeError: unhashable type: 'list'. Any help would be of great help.

ceeka9388
  • 69
  • 8

1 Answers1

1

In this case you need to use fixed-sized queue as shown below:

Try:

from collections import deque

a= [1,2,3,4,5,6,7,8,9,10,11,12]
wts= [0.055555556,0.055555556,0.055555556,0.055555556,0.055555556,0.055555556,0.055555556,0.055555556,0.055555556,0.10,0.10,0.30]
len_a = len(a)

# Create a fixed sized queue
q = deque(maxlen=len_a)

# Add list a to q
q.extend(a)

# See the q
print('q: ', q)

i = 0
result = []

while i < len(a):
    val = sum([x*y for x, y in zip(q, wts)])
    q.append(val)
    result.append(float(round(val, 2)))
    i += 1

print('result: ', result)

# Output
q:  deque([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], maxlen=12)
result:  [8.2, 7.76, 7.85, 7.95, 8.18, 8.42, 8.63, 8.79, 8.89, 8.93, 8.89, 8.77]
JkShaw
  • 1,927
  • 2
  • 13
  • 14
  • Thanks for this reply. This Deque is a new concept I learnt today. – ceeka9388 May 13 '17 at 07:07
  • @ceeka9388, it can be done using `list` also, it's just you need to `pop` from `0th` position and `append` the `val`, but using `queue` is much faster. – JkShaw May 13 '17 at 07:11
  • I need some help in applying this to a dataframe as function. Any suggestions would be of great help here. – ceeka9388 May 17 '17 at 07:02
  • @ceeka9388, sorry couldn't reply earlier. i don't know `panda`, but looking at the error, it seems like `groupby` takes `hashable` type as argument, as you know `list` is `unhashable` so the error. please convert it into `tuple` as follows: `s1.groupby(('Column A', 'Column B', 'Column C'))`. If this doesn't solve your problem post a new question and you would receive the answer. – JkShaw May 18 '17 at 05:10