Pandas可以读取和修改单个Excel文件工作表(选项卡)而无需修改文件的其余部分吗?

时间:2015-01-25 22:38:06

标签: python excel pandas

许多电子表格都有公式和格式,用于读取和写入Excel文件的Python工具无法忠实再现。这意味着我想以编程方式创建的任何文件必须是我从头开始创建的东西,然后其他Excel文件(具有上述复杂性)必须引用该文件(这会产生各种其他依赖性问题)。

我对Excel文件'tabs'的理解是它们实际上只是XML文件的集合。那么,是否可以使用pandas(或其中一个底层的读/写引擎,如xlsxwriter或openpyxl来修改其中一个选项卡,其他选项卡(其中有更多邪恶的东西)完好无损?

编辑:我将尝试通过一个例子进一步阐述问题。

  • Excel Sheet test.xlsx有四个选项卡(又名工作表):Sheet1,Sheet2,Sheet3,Sheet4
  • 我使用pandas.read_excel()
  • 将Sheet3读入DataFrame(我们称之为df)
  • Sheet1和Sheet2包含公式,图形和各种格式,openpyxl和xlrd都无法成功解析,Sheet4包含其他数据。我根本不想触摸这些标签。
  • Sheet2实际上对Sheet3上的单元格有一些引用
  • 我对df进行了一些编辑,现在想把它写回到sheet3,保持其他工作表不受影响(以及工作簿中其他工作表对它的引用完整)

我能这样做,如果是的话,怎么做?

6 个答案:

答案 0 :(得分:11)

关于excel和python(特别是pandas)之间的交互,我有一个类似的问题,我被提到了这个问题。

感谢stackoverflow社区的一些指示,我找到了一个名为xlwings的软件包,它似乎涵盖了HaPsantran所需的许多功能。

使用OP的例子:

使用现有的excel文件,您可以通过在excel中命名并将其导入到要导入到pandas的数据块(Sheet3)中的锚点并执行:

# opened an existing excel file

wb = Workbook(Existing_file)

# Find in the excel file a named cell and reach the boundary of the cell block (boundary defined by empty column / row) and read the cell 

df = Range(Anchor).table.value

# import pandas and manipulate the data block
df = pd.DataFrame(df) # into Pandas DataFrame
df['sum'] = df.sum(axis= 1)

# write back to Sheet3
Range(Anchor).value = df.values

测试了这个实现并没有改变excel文件

中现有的公式

如果这可以解决您的问题以及是否有任何我可以提供的帮助,请告诉我。

对xlwings开发人员的高度赞扬,他们使这成为可能。

以下是来自@jamzsabb的进一步问题后我之前回答的更新,并反映了xlwings更新为> = 0.9.0后更改的API。

import xlwings as xw
import pandas as pd
target_df = xw.Range('A7').options(pd.DataFrame, expand='table').value # only do this if the 'A7' cell (the cell within area of interest) is in active worksheet
#otherwise do:
#sht = xw.Book(r'path to your xlxs file\name_of_file.xlsx`).sheets['name of sheet']
#target_df = sht.Range('A7').options(pd.DataFrame, expand='table').value # you can also change 'A7' to any name that you've given to a cell like 'interest_table`

答案 1 :(得分:5)

我90%有信心“能pandas这样做”的答案是否定的。发布负面信息很难,因为总有可能会有一些我错过的聪明,但这是一个案例:

可能的界面引擎是xlrd/xlwt/xlutilsopenpyxlxlsxwriter。没有一个适用于您的目的,因为xlrd/wt不支持所有公式,xlsxwriter无法修改现有的xlsx文件,openpyxl会丢失图像和图表。

由于我经常需要这样做,所以我只考虑将简单的输出写入单独的文件,然后直接调用win32api来复制工作簿之间的数据,同时保留我同事的所有闪亮数字。这很烦人,因为这意味着我必须在Windows而不是* nix下进行,但它可以工作。

如果你在Windows下工作,你可以做类似的事情。 (我想知道在这种情况下使用这种方法添加本机插入选项是否有意义,或者我们应该只发布一个食谱。)


P.S。:这个问题让我不时感到恼火,因为我已经想到了足够的现代Excel格式,以便为其中一个库添加对此的支持。

PPS:但是因为忽略了你没有处理的东西并且没有修改它们似乎很容易,没有人似乎支持它的事实让我觉得有些令人头疼,而且Redmond参与其中我愿意相信它。 @ john-machin会知道细节,如果他的话......

答案 2 :(得分:3)

我要添加一个使用openpyxl的答案。从2.5版开始,您可以将图表保存在现有文件中(有关该问题的更多详细信息,请参见here)。

出于演示目的,我按照OP准则使用熊猫创建了xlsx文件。名为“ Sheet2”的标签具有引用“ Sheet3”的公式,并包含一个图表。

import pandas as pd

df = pd.DataFrame({'col_a': [1,2,3],
                  'col_b': [4,5,6]})

writer = pd.ExcelWriter('test.xlsx', engine='xlsxwriter')
df.to_excel(writer, sheet_name='Sheet1', index=False)
workbook=writer.book
worksheet = writer.sheets['Sheet1']
df.head(0).to_excel(writer, sheet_name='Sheet2', index=False)
workbook=writer.book
worksheet = writer.sheets['Sheet2']
for i in range(2, len(df) + 2):
    worksheet.write_formula('A%d' % (i), "=Sheet3!A%d" % (i))
    worksheet.write_formula('B%d' % (i), "=Sheet3!B%d" % (i))
chart = workbook.add_chart({'type': 'column'})

chart.add_series({'values': '=Sheet2!$A$2:$A$4'})
chart.add_series({'values': '=Sheet2!$B$2:$B$4'})

worksheet.insert_chart('A7', chart)

df.to_excel(writer, sheet_name='Sheet3', index=False)
df.to_excel(writer, sheet_name='Sheet4', index=False)

writer.save()

运行上面的代码后,预期为test.xlsx:

test.xlsx after first block of code

然后,如果我们使用openpyxl运行以下代码,则可以在“ Sheet3”中修改数据,同时在“ Sheet2”中保留公式和图表,并且更新后的数据现在位于此文件中。

from openpyxl import load_workbook

wb = load_workbook('test.xlsx')
ws = wb['Sheet3']
ws['B2'] = 7
ws['B3'] = 8
ws['B4'] = 9
wb.save('test.xlsx')

运行第二个代码块后,预期为test.xlsx:

test.xlsx after second block of code

答案 3 :(得分:1)

据我所知,熊猫并没有做到这一点。

我编写了一些小型实用程序库pandasxltable(基于openpyxl),以促进excel模板与熊猫数据框之间的交互。该库允许您从数据框中获取数据框并更新Excel数据表(不是标签,而是标签的一部分)。

答案 4 :(得分:0)

如果您正在谈论表格'作为'标签',然后可以通过使用parse(sheet_name)功能访问特定标签来仅修改其中一个标签。

这里有一个例子: Reading an Excel file in python using pandas

写回excel,(在控制工作表的同时)使用to_excel函数,在这里: http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.to_excel.html

答案 5 :(得分:0)

必需:存在excel文件的调用路径。

输入:列表字符串。

输出:附加行。

forcats::fct_explicit_na()

或使用此按钮自动创建行,行。

library(dplyr)
library(forcats)

# Make sample data vars factors
dat <- dat %>%
  mutate(across(starts_with("s_"), as.factor))

# Add 'No' as factor level
dat %>%
  mutate(across(starts_with("s_"), fct_explicit_na, "No"))

# A tibble: 10 x 6
      id     x s_0   s_1   s_2   s_3  
   <dbl> <dbl> <fct> <fct> <fct> <fct>
 1     1     5 75    A     4     110  
 2     2     9 36    No    No    921  
 3     3    11 13    B     7     769  
 4     4    11 34    C     2     912  
 5     5    11 No    C     No    835  
 6     6    13 39    No    4     No   
 7     7    14 45    B     4     577  
 8     8    19 42    D     6     No   
 9     9    20 4     No    7     577  
10    10    13 28    No    3     573