简体   繁体   English

遍历电子表格中的行,在每一行中运行一个函数,然后将结果输出回同一行的末尾

[英]Looping through rows from a spreadsheet, running a function through each row and outputting the result back to the end of the same row

This is a tough one, but I've been stuck for 2 weeks and I would appreciate if someone could help me on this. 这是一个艰难的过程,但是我已经被困了两个星期,如果有人可以帮助我,我将不胜感激。 Basically, I've got a spreadsheet where the first row is like this (I was not able to paste the spreadsheet here and keep it formatted in an understandable way): A1=Material, B1=Jan/15, C1=Feb/15, ..., AW=Dec/18. 基本上,我有一个电子表格,其中第一行是这样的(我无法将电子表格粘贴到此处并以易于理解的方式对其进行格式化):A1 =材料,B1 = 1月15日,C1 = 2月15日,...,AW = Dec / 18。 The material list (A column) goes all the way from A2 to A6442 and each line has a part number. 物料清单(A列)从A2一直到A6442,并且每行都有零件编号。 From B2:B6442 each line represents a quantity for each part. 从B2:B6442开始,每行代表每个零件的数量。 So, row B2:AW2 would be the consumption for the part on B1 from jan/15 to dec/18. 因此,行B2:AW2是B1上从jan / 15到dec / 18的部分的消耗量。

Considering the above, what I want to do is loop through every single row, apply a def (triple_exponential_smoothing) and return the last 6 numbers from the series back to Excel, on cells AR to AW (ex. for the 2nd row, AR2:AW2). 考虑到上述情况,我要做的是遍历每一行,应用def(triple_exponential_smoothing),然后将序列中的最后6个数字返回到Excel中的AR到AW单元格(例如第二行,AR2: AW2)。 I would use the first 3.5 years (B2:AQ2) as base for calculation for the remaining 6 months of the year (AR2:AW2). 我将使用前3.5年(B2:AQ2)作为计算一年中其余6个月(AR2:AW2)的基础。 When I run it with a defined range (as per below), it works: 当我以定义的范围(如下所示)运行它时,它可以工作:

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

When I run a loop instead I cannot even get the output from the function, let alone write it back to Excel. 当我运行循环时,我什至无法从函数中获取输出,更不用说将其写回到Excel了。 My code so far is the below: 到目前为止,我的代码如下:

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))

Am I missing something? 我想念什么吗? I am open to other ways of doing it, as long as I can do all the rows at once. 只要我可以一次完成所有行,就可以采用其他方式。

Thank you all in advance. 谢谢大家。

The simplest way to do this would be to create a user defined function (UDF) that worked on one row, you could then copy that down as far as required. 最简单的方法是创建在一行上工作的用户定义函数(UDF),然后可以根据需要向下复制该函数。

For better performance you could read the whole data range into Python, loop through each row, writing the results to a list of lists or a Numpy array, then write all the results back to an Excel range in a single operation. 为了获得更好的性能,您可以将整个数据范围读入Python,遍历每一行,将结果写到列表列表或Numpy数组中,然后通过一次操作将所有结果写回到Excel范围。 That could also conveniently be written as a UDF. 也可以方便地将其编写为UDF。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 遍历 Df 并将结果合并到特定行 - Looping through Df and Merge result into a particular row 如何在循环遍历每一行以运行 function 时删除 CSV 文件中的一行? - How to remove a row in a CSV file while looping through each row to run a function? 通过遍历函数中的每一行来修改数据框 - Modifying the dataframe by looping through every row in function 循环抓取数据并输出结果 - Looping through scraped data and outputting the result 如何遍历每一行并将结果保存在同一行但在不同的列中? - how do I loop through each row and save the result in same row but in difference column? 遍历 Pandas Dataframe Dict,并从它们中输出相同的行 - Iterating Through Pandas Dataframe Dict, and Outputting The Same Row From All of Them 如何使用openpyxl遍历excel电子表格中的每一行 - how to loop through each row in excel spreadsheet using openpyxl 循环遍历 2 个 Pandas 数据帧并将行值传递给计算距离的函数 - Looping through 2 Pandas Dataframes and passing row values to a function calculating distance 有没有办法使用 lambda function 将行中的值添加到下一行来遍历行? - Is there a way to iterate through the rows using the lambda function to add values from the a row to the following row? 遍历数据框中选定列的行以“清理”每一行 - Iterating through rows of selected column in dataframe to “clean” each row
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM