Есть ли способ разработать формулу для столбца, используя предыдущие строки в Python, не используя для l oop? - PullRequest
2 голосов
/ 01 марта 2020

У меня есть массив numpy размером 5000 на 7. Я хочу вычислить столбец 7 для всех строк от позиции 200 до 4999 по следующей формуле:

набор данных [i, 7] = сумма ( набор данных [i-200,0] + набор данных [i-199,0] + набор данных [i-198,0] + ... + набор данных [i-1,0]) / 200

У меня есть попробовал следующее - что работает -:

import numpy as np

dataset = np.random.rand(numberOfDataItems, 7)
for i in range(200,numberOfDataItems):
    dataset[i,6] = np.sum(dataset[i-200:i,3])/200

Я сомневаюсь, что можно устранить внешний l oop, используя другой подход, используя numpy.

1 Ответ

1 голос
/ 02 марта 2020

Вот решение, использующее np.r_, slicing и skimage.util.view_as_ windows.

Для простоты я просто использую np.arange в качестве данных. В случае нескольких серий данных вы можете повторить это для всех строк, для которых вы хотите получить обратное усреднение:

from skimage.util import view_as_windows

numberOfDataItems=500
sumwindow=100
data=np.arange(numberOfDataItems)

Используя np.r_, я могу пошагово свернуть эти данные, чтобы сделать их в форме массива с размером len (data) xlen (data)

b = np.r_[data,np.full(len(data)-1,data[:-1])]
c=view_as_windows(b,len(data))
c
Out[]: 
array([[ 0,  1,  2, ..., 47, 48, 49],
       [ 1,  2,  3, ..., 48, 49,  0],
       [ 2,  3,  4, ..., 49,  0,  1],
       ...,
       [47, 48, 49, ..., 44, 45, 46],
       [48, 49,  0, ..., 45, 46, 47],
       [49,  0,  1, ..., 46, 47, 48]])

По сути, это np.roll (data) с размером шага i в столбце i, но без al oop. Теперь я мог бы суммировать первые, скажем, 10 элементов в столбце 0 как значения для работы для столбца 10 и так далее для последующих столбцов.

d=c[:sumwindow,:-sumwindow].sum(axis=0)/sumwindow
Out[]: 
array([ 4.5,  5.5,  6.5,  7.5,  8.5,  9.5, 10.5, 11.5, 12.5, 13.5, 14.5,
       15.5, 16.5, 17.5, 18.5, 19.5, 20.5, 21.5, 22.5, 23.5, 24.5, 25.5,
       26.5, 27.5, 28.5, 29.5, 30.5, 31.5, 32.5, 33.5, 34.5, 35.5, 36.5,
       37.5, 38.5, 39.5, 40.5, 41.5, 42.5, 43.5])

Теперь легко увидеть, что если бы мы хотели возьмите среднее значение из последних 10 элементов в каждом столбце, тогда значение 4.5 будет значением для строки 10, и значение, конечно, будет увеличиваться на 1 для каждого столбца.

e=np.array([data,data],dtype=float)
e[1,sumwindow:]=d
Out[]: 
array([[ 0. ,  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. , 27. , 28. , 29. , 30. , 31. , 32. ,
        33. , 34. , 35. , 36. , 37. , 38. , 39. , 40. , 41. , 42. , 43. ,
        44. , 45. , 46. , 47. , 48. , 49. ],
       [ 0. ,  1. ,  2. ,  3. ,  4. ,  5. ,  6. ,  7. ,  8. ,  9. ,  4.5,
         5.5,  6.5,  7.5,  8.5,  9.5, 10.5, 11.5, 12.5, 13.5, 14.5, 15.5,
        16.5, 17.5, 18.5, 19.5, 20.5, 21.5, 22.5, 23.5, 24.5, 25.5, 26.5,
        27.5, 28.5, 29.5, 30.5, 31.5, 32.5, 33.5, 34.5, 35.5, 36.5, 37.5,
        38.5, 39.5, 40.5, 41.5, 42.5, 43.5]])

При просмотре начальных данных и результатов вместе, первые (sumwindow) значения совпадают, и с этого момента они всегда являются средними значениями (sumwindow) ранее, как вы это делали для окна 200 в Ваш пример.

Надеюсь, это решение соответствует вашим потребностям.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...