Цикл по строкам из электронной таблицы, запуск функции по каждой строке и вывод результата в конец той же строки

1

Это тяжело, но я застрял в течение 2 недель, и я был бы признателен, если бы кто-то помог мне в этом. В принципе, у меня есть таблица, где первая строка похожа на это (я не смог вставить электронную таблицу здесь и сохранить ее в форматированном виде): A1 = Material, B1 = Jan/15, C1 = Feb/15 ,..., AW = Dec/18. Список материалов (столбец A) проходит от A2 до A6442, и каждая строка имеет номер детали. Из B2: B6442 каждая строка представляет количество для каждой части. Таким образом, строка B2: AW2 будет потреблением части на B1 от jan/15 до dec/18.

Учитывая вышеизложенное, то, что я хочу сделать, это цикл через каждую строку, применить def (triple_exponential_smoothing) и вернуть последние 6 чисел из серии обратно в Excel, на ячейки AR до AW (например, для второй строки, AR2: AW2). Я бы использовал первые 3,5 года (B2: AQ2) в качестве базы для расчета за оставшиеся 6 месяцев года (AR2: AW2). Когда я запускаю его с определенным диапазоном (как указано ниже), он работает:

series = xw.Range((2,2),(2, 37)).value 

Когда я запускаю цикл вместо этого, я даже не могу получить результат из этой функции, не говоря уже о ее возврате в Excel. Мой код до сих пор ниже:

import os
import xlwings as xw

#Defining folder
os.chdir('G:\...\Reports')

#importing data
wb = xw.Book('sheet.xlsx')
sht = wb.sheets['sheet']
series = [sht.range((i,2),(i, 37)).value for i in range(2, 6443)]

# Holt Winters formula

def initial_trend(series, slen):
     sum = 0.0
     for i in range(slen):
          sum += float(series[i+slen] - series[i]) / slen
    return sum / slen

def initial_seasonal_components(series, slen):
     seasonals = {}
     season_averages = []
    n_seasons = int(len(series)/slen)
    # compute season averages
    for j in range(n_seasons):
         season_averages.append(sum(series[slen*j:slen*j+slen])/float(slen))
# compute initial values
for i in range(slen):
    sum_of_vals_over_avg = 0.0
    for j in range(n_seasons):
        sum_of_vals_over_avg += series[slen*j+i]-season_averages[j]
    seasonals[i] = sum_of_vals_over_avg/n_seasons
return seasonals

def triple_exponential_smoothing(series, slen, alpha, beta, gamma, n_preds):
    result = []
    seasonals = initial_seasonal_components(series, slen)
    for i in range(len(series)+n_preds):
        if i == 0: # initial values
             smooth = series[0]
             trend = initial_trend(series, slen)
             result.append(series[0])
             continue
        if i >= len(series): # we are forecasting
             m = i - len(series) + 1
             result.append((smooth + m*trend) + seasonals[i%slen])
        else:
            val = series[i]
            last_smooth, smooth = smooth, alpha*(val-seasonals[i%slen]) + (1-alpha)*(smooth+trend)
            trend = beta * (smooth-last_smooth) + (1-beta)*trend
            seasonals[i%slen] = gamma*(val-smooth) + (1-gamma)*seasonals[i%slen]
            result.append(smooth+trend+seasonals[i%slen])
    return result

#printing results for the function looped through all rows    

print(triple_exponential_smoothing(series, 12, 0.96970912, 0.07133329, 0, 12))

Я что-то пропустил? Я открыт для других способов сделать это, пока я могу делать все строки сразу.

Спасибо всем заранее.

Теги:
excel
python-3.x
holtwinters
xlwings

1 ответ

0
Лучший ответ

Самый простой способ сделать это - создать определенную пользователем функцию (UDF), которая работает в одной строке, тогда вы можете скопировать ее до тех пор, пока это необходимо.

Для лучшей производительности вы можете прочитать весь диапазон данных в Python, пропустить каждую строку, записать результаты в список списков или массив Numpy, а затем записать все результаты обратно в диапазон Excel за одну операцию. Это также удобно записывать как UDF.

  • 0
    Спасибо, Даг, я ценю время, которое вы потратили, чтобы дать мне ответ. Я смог найти ответ сам неделю назад. Учитывая, что цикл, который перебирает строки Excel, преобразует их в списки внутри списков, я мог получить доступ к каждому списку, указав расположение (что-то вроде «series [6]»). Учитывая это, я заменил значение позиции на переменную и прошел через нее в качестве входных данных для функции triple_exponential_smoothing и результатов, которые я добавил обратно в Excel.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню