Excel中pandas的公式评估

说我有一个这样的字典,其关键是Excel中的单元格引用,值是公式或整数。

input_dict = { "B25": "=B2*B4", "C25": "=C2*C4", "D25": "=D2*D4", "E25": "=E2*E4", "F25": "=F2*F4", "G25": "=G2*G4", "B22": 0, "C22": "=SUM(B22:B28)", "D22": "=SUM(C22:C28)", "E22": "=SUM(D22:D28)", "F22": "=SUM(E22:E28)", "G22": "=SUM(F22:F28)", "B28": "=B19*B20*B22", "C28": "=C19*C20*C22", "D28": "=D19*D20*D22", "E28": "=E19*E20*E22", "F28": "=F19*F20*F22", "G28": "=G19*G20*G22", "B2": 1000, "C2": 900, "D2": 880, "E2": 860, "F2": 840, "G2": 800, "B4": 0.95, "C4": 0.90, "D4": 0.80, "E4": 0.80, "F4": 0.70, "G4": 0.60, "B19": 0.001, "C19": 0.001, "D19": 0.001, "E19": 0.001, "F19": 0.001, "G19": 0.002, "B20": 4, "C20": 3, "D20": 4, "E20": 4, "F20": 3, "G20": 4 } 

如何对这种types的数据进行计算。

我的做法是将字典转换为数据框,并对其进行计算,但我卡住了。

 df = pd.DataFrame(list(input_dict.items())) 

df的输出如下所示。

  0 1 0 G22 =SUM(F22:F28) 1 G4 0.6 2 F2 840 3 D2 880 4 C20 3 5 C4 0.9 6 B28 =B19*B20*B22 7 F25 =F2*F4 8 B25 =B2*B4 9 G25 =G2*G4 10 C28 =C19*C20*C22 11 G28 =G19*G20*G22 12 F22 =SUM(E22:E28) 13 C25 =C2*C4 14 B19 0.001 15 E4 0.8 16 D22 =SUM(C22:C28) 17 D4 0.8 18 G2 800 19 E28 =E19*E20*E22 20 D20 4 21 G20 4 22 E25 =E2*E4 23 F20 3 24 G19 0.002 25 E22 =SUM(D22:D28) 26 C2 900 27 D25 =D2*D4 28 E2 860 29 D28 =D19*D20*D22 30 C19 0.001 31 F28 =F19*F20*F22 32 B20 4 33 B2 1000 34 F4 0.7 35 E19 0.001 36 D19 0.001 37 B4 0.95 38 B22 0 39 F19 0.001 40 C22 =SUM(B22:B28) 41 E20 4 

如何在Python中执行类似Excel的计算?

预期产出如下

 { "B25": "950", "C25": "810", "D25": "704", "E25": "688", "F25": "588", "G25": "480", "B22": 0, "C22": 950, "D22": 1757.15, "E22": 2454.1214, "F22": 3710.908, "G22": 4161.220736, "B28": 0, "C28": -2.85, "D28": -7.0286, "E28": -9.8164856, "F28": -9.396914743, "G28": -29.687264, "B2": 1000, "C2": 900, "D2": 880, "E2": 860, "F2": 840, "G2": 800, "B4": 0.95, "C4": 0.90, "D4": 0.80, "E4": 0.80, "F4": 0.70, "G4": 0.60, "B19": 0.001, "C19": 0.001, "D19": 0.001, "E19": 0.001, "F19": 0.001, "G19": 0.002, "B20": 4, "C20": 3, "D20": 4, "E20": 4, "F20": 3, "G20": 4 } 

你需要一些东西来parsingExcel公式,并将它们转换成允许执行计算的表单。

一个快速search带来了pycel作为这个最有前途的Python库。 它不支持所有 Excel的函数和语法,但它可能应该支持你需要的东西,它绝对支持你发布的例子中的公式。

另请参阅类似SO问题的答案 。 正如它所提到的,你也可以实际连接到Excel,让它执行所有的计算,然后只读取结果。 一种方法是使用win32com库,详见前面提到的答案。

你可以使用正则expression式(正则expression式)和Python的eval函数。

我们假设我们有

 d = {'A1': '=A2+A3', 'A2': '=SUM(A3:A5)', 'A3': 3, 'A4': 6, 'A5': -1, ...} 

整个function看起来像

 import re def g(s): """Excel-like evaluation with recurrence""" if isinstance(s,(int, float)): return s s=re.sub(r'=', '', s) s=re.sub(r'SUM\(([AZ])([0-9]):([AZ])([0-9])\)','sum([g(d[chr(i)+str(j)]) for j in range(\g<2>,\g<4>+1) for i in range(ord("\g<1>"), ord("\g<3>")+1)])',s) s=re.sub(r'([AZ][0-9])',r'g(d["\1"])',s) return eval(s) 

例如

 >>> print(g(d['A1'])) 11 

让我们来看看单个步骤:

  • 首先我们摆脱了= 。 也可以写一个testing,只有评估公式,如果它以a =开头,直到读者。
  • re.sub(r'([AZ][0-9])', r'g(d["\g<1>"])', any_string)replace一个大写字母和一个数字组例如'A3')和它的字典查找(ex'g(d [“A3”]))

    • 如果新的单元格值仍然是一个公式(重复),我们需要再次应用g()
    • 注意:如果在Excel中出现类似“A $ 3”或“$ AB $ 4”的条目,可以使用r'$?([AZ]+)$?([0-9])'作为search模式,作为替代。 r'd["\g<1>\g<2>"]'作为替代。
  • 然后我们可以用eval()来评估这个string。 到目前为止,可以使用所有实现的Python操作,如+, -, *, /, //, %, etc.

  • 所有其他函数都需要通过用Pythonexpression式replace它们来手动实现。 她是SUM(A3:B10)一个例子:

    r'SUM\(([AZ])([0-9]):([AZ])([0-9])\)'我们search公式。

    [chr(i)+str(j) for j in range(\g<2>,\g<4>+1) for i in range(ord("\g<1>"), ord("\g<3>")+1)]]给我们所有的表格索引。 然后我们将g(d[...])应用于它们中的每一个(复发)并且取其总和。

这当然可以扩展到任何Excel公式。