【问题标题】:How to update values in Excel DURING a calculation and based on previous results of that calculation?如何在计算期间并根据该计算的先前结果更新 Excel 中的值?
【发布时间】:2019-03-11 17:33:34
【问题描述】:

我正在研究一种模型来匹配供需。对模型的简短解释:我有几个“供应”点和一定的资源单位和几个“需求”点。其目的是通过最小化运输距离,将可用资源从“供应”点“排放”到最近的“需求”点。

在 ArcGIS 中,我已经找到了距离每个“供应”点最近的“需求”点和相应的距离。此外,我还有“供应”点生产的资源量和“需求”点所需的资源量。我将结果存储在 Excel 表格中,并根据从小到大的距离对它们进行排序,以便我可以使用 Python 进一步处理它们。

我做了一个简单概述的表格,其中有 2 个“供应”点和几个“需求”点。 “供应”点 1 的可用资源为 10,“供应”点 2 的可用资源为 20。所有“需求”点的需求各不相同。 The Excel table looks like this:

使用该 Excel 表,我想计算从每个“供应”点 ('D') 到最近的(和第二个最接近的……n 最近的)“需求”点('E' ),直到“供应”点的值为 0/完全分布。我想在附加列('F')中存储从“供应”到“需求”的运输量的值 为此,我编写了以下代码:

for row in range(1,sheet.max_row+1):
   if sheet['D'+str(row)].value !=0 and sheet['E'+str(row)].value !=0:
    for row in range(1,sheet.max_row+1):
        if sheet['D'+str(row)].value > sheet['E'+str(row)].value:
            sheet['F'+str(row)].value = sheet['E'+str(row)].value
            sheet['D'+str(row)].value = sheet['D'+str(row)].value - sheet['E'+str(row)].value
            sheet['E'+str(row)].value = 0
        if sheet['D'+str(row)].value < sheet['E'+str(row)].value:
            sheet['F'+str(row)].value = sheet['D'+str(row)].value
            sheet['E'+str(row)].value = sheet['E'+str(row)].value -sheet['D'+str(row)].value
            sheet['D'+str(row)].value = 0
        if sheet['D'+str(row)].value == sheet['E'+str(row)].value:
            sheet['F'+str(row)].value = sheet['E'+str(row)].value
            sheet['D'+str(row)].value = 0
            sheet['E'+str(row)].value = 0

上面的代码有效并计算了列表长度上所有行的列 F 中我想要的所有值。

但是,还有一个问题:

现在的代码编写方式,并没有正确更新供求值。所以它没有考虑到,如果一些资源从一个“供应”点供应到一个“需求”点,那么“供应”单元格中的可用资源量会发生变化,以便随后进行计算。

更具体地说,“供应”点 1 只有 10 个可用的单位可以“分发”。在下面的示例表中,“供应”点 1 只能向第一个和第二个最近的“需求”点供应资源,直到“供应”点 1 的所有资源都用完(6 个单位到“需求点”,DEMAND_FID = 10和 4 个单位到“需求点” DEMAND_FID = 11)。之后,“供应”点 1(SUPPLY_R)的所有单元都“消失”,DEMAND_FID = 10 的“需求点”的需求得到满足,DEMAND_FID = 11 的“需求点”的需求从 6 减少到 1。因此,甚至不应该计算第 6 行,因为“供应”点 1 无法向“需求点”提供任何额外资源 因此,我想在计算完一行后更新 SUPPLY_R 和 DEMAND_R 的值。

The “ideal” table with results should look like this:

如何根据计算中的前几行来解决在一行中更改一个值的问题?

我尝试使用字典中的值更新新的“供应”和“需求”值,但这并没有给出预期的结果。

【问题讨论】:

  • 您实际上是在伪装成 Python 的 VBA 编码。如果您将 Excel 视为可视化/导出工具,将所有值读入 Pandas 数据框import pandas as pd; df = pd.read_excel('input.xlsx') 并在那里进行计算,然后最终通过df.to_excel('output.xlsx) 将其导出到 Excel,实际上会简单得多。
  • 您可以在 excel 中设置这种类型的模型,然后使用求解器迭代到“最佳”解决方案...
  • @ycx 是的,我知道数据框非常适合分析 Excel 工作表,并且我也在使用它们。但是在这种情况下,Dataframe 如何帮助我(更好地)解决我的问题?是否有可以与 Dataframe 一起使用的特殊功能?
  • @CaroW 您可以利用 pandas 库中的 .groupby().transform() 以及累积总和来实现您的要求。之后,只需将它们重新按原始索引重新排列即可。尝试一下并使用 pandas 的一些代码编辑您的问题,我可能会从那里开始为您提供进一步的帮助。

标签: python excel python-2.7 arcmap


【解决方案1】:

我现在实际上解决了这个问题。 我正在使用字典来更新每一行中的值 (抱歉现在列的编号有所不同,但希望方法变得清晰)

dict1={1: 156, 2: 5, 3: 207, ....., 226: 142}
dict2={{1: 23, 2: 18, 3: 23,....., 1530: 9}

for row in range(2,sheet.max_row+1):
   sheet['F'+str(row)].value = dict1[sheet['C'+str(row)].value] 
   sheet['I'+str(row)].value = dict2[sheet['D'+str(row)].value]

   if sheet['F'+str(row)].value > sheet['I'+str(row)].value:
          sheet['L'+str(row)].value = sheet['I'+str(row)].value 
          if sheet['L'+str(row)].value <= 0:
                sheet['L'+str(row)].value = None
          sheet['F'+str(row)].value = sheet['F'+str(row)].value -sheet['I'+str(row)].value
          sheet['I'+str(row)].value = 0
          if sheet['L'+str(row)].value > 0:
                sheet['M'+str(row)].value = sheet['C'+str(row)].value
          else:
                sheet['M'+str(row)].value = None
          if sheet['L'+str(row)].value > 0:
                sheet['N'+str(row)].value = sheet['D'+str(row)].value
          else:
                sheet['N'+str(row)].value = None

      #2 different methods to update the dictionary
          dict1_1={sheet['C'+str(row)].value :sheet['F'+str(row)].value}
          dict1.update(dict1_1)
          sheet['F'+str(row)].value = dict1[sheet['C'+str(row)].value]
          dict2[sheet['D'+str(row)].value]= sheet['I'+str(row)].value
          sheet['I'+str(row)].value = dict2[sheet['D'+str(row)].value]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-21
    • 1970-01-01
    • 1970-01-01
    • 2014-04-01
    • 1970-01-01
    相关资源
    最近更新 更多