pandas读取excel值而不是公式

16 人关注

有没有办法让pandas只从excel中读入数值而不读入公式?除非我在运行代码前手动保存excel文件,否则公式会被读成NaN。我只是用pandas的基本读excel功能工作。

import pandas as pd
df = pd.read_excel(filename, sheetname="Sheet1")

如果我在运行代码之前已经进入并保存了文件,这将读取数值。但是,在运行代码更新一个新的工作表后,如果我没有进去保存文件,并试图再次运行这个代码,它将把公式读成NaN,而不是仅仅读值。有谁知道有什么解决方法可以用pandas从excel中读取数值吗?

5 个评论
你的excel电子表格是否处于自动计算模式?
是的公式被设置为自动计算。
奇怪,你的原始文件是由人保存的,还是在你转卖之前来自一个程序?
由一个人保存,我们拉入数据,然后在此基础上创建公式。但我们拉来的数据只是复制和粘贴到一个文件中,然后保存。
我也遇到了类似的问题,但它只发生在前几行,其余的都是由公式处理的数值。
python
excel
pandas
Colton T
Colton T
发布于 2017-01-18
3 个回答
RobatStats
RobatStats
发布于 2021-01-29
已采纳
0 人赞同

这很奇怪。pandas的正常行为是读取数值,而不是公式。很可能,问题出在你的Excel文件中。可能是你的公式指向了其他文件,或者它们返回的值被pandas认为是nan。

在第一种情况下,工作表需要被更新,对此pandas无能为力(但请继续阅读)。

在第二种情况下,你可以通过在read_excel中设置明确的nan值来解决。

pd.read_excel(path, sheetname="Sheet1", na_values = [your na identifiers])

至于第一种情况,作为一种使你的工作更容易的变通方案,你可以用xlwings将你的手工操作自动化。

import pandas as pd
import xlwings as xl
def df_from_excel(path):
    app = xl.App(visible=False)
    book = app.books.open(path)
    book.save()
    app.kill()
    return pd.read_excel(path)
df = df_from_excel(path to your file)

如果你想在你的excel文件中保留这些公式,只要把文件保存在不同的位置(book.save(different location))。然后你就可以用shutil摆脱这些临时文件了。

是的,我知道我可以自动保存,我只是想弄清楚是否有办法解决这个问题。这些公式并不指向其他文件,它们只是从一列中取值,然后减去其他列的值之和,所以它们只是返回数字。
在2020年9月写下这篇文章 - pd.read_excel()现在可以读取数值了,即使公式指向其他文件。
在2021年1月写的 - pd.read_excel()只有在笔记本被 "打开 "时才会读入数值,因此需要用xlwings模拟打开和保存文件。据我所知,公式在工作簿被打开之前不会被计算,这就是为什么当工作簿只被脚本更新时,带有公式的单元格没有与之相关的值的原因
jeansergecardinal
jeansergecardinal
发布于 2021-01-29
0 人赞同

我遇到了这个问题,我通过将一个图形移到我正在阅读的第一行下面来解决这个问题。看来图形的位置可能导致问题。

Rajat Tyagi
Rajat Tyagi
发布于 2021-01-29
0 人赞同

你可以使用xlrd来读取这些值。 首先你应该刷新你的excel表,你也在用python自动更新数值。你可以使用下面的函数 file = myxl.xls

import xlrd
import win32com.client
import os
def refresh_file(file):
    xlapp = win32com.client.DispatchEx("Excel.Application")
    path = os.path.abspath(file)
    wb =  xlapp.Wordbooks.Open(path)
    wb.RefreshAll()
    xlapp.CalculateUntilAsyncqueriesDone()
    wb.save()
    xlapp.Quit()

文件刷新后,你可以开始阅读内容。

workbook = xlrd.open_workbook(file)
worksheet = workbook.sheet_by_index(0)
for rowid in range(worksheet.nrows):