Làm cách nào để lưu một trang tính mới trong một tệp excel hiện có, bằng cách sử dụng Pandas?


87

Tôi muốn sử dụng tệp excel để lưu trữ dữ liệu được xây dựng bằng python. Vấn đề của tôi là tôi không thể thêm trang tính vào tệp excel hiện có. Ở đây, tôi đề xuất một mã mẫu để làm việc để giải quyết vấn đề này

import pandas as pd
import numpy as np

path = r"C:\Users\fedel\Desktop\excelData\PhD_data.xlsx"

x1 = np.random.randn(100, 2)
df1 = pd.DataFrame(x1)

x2 = np.random.randn(100, 2)
df2 = pd.DataFrame(x2)

writer = pd.ExcelWriter(path, engine = 'xlsxwriter')
df1.to_excel(writer, sheet_name = 'x1')
df2.to_excel(writer, sheet_name = 'x2')
writer.save()
writer.close()

Mã này lưu hai DataFrame vào hai trang tính, có tên tương ứng là "x1" và "x2". Nếu tôi tạo hai DataFrame mới và cố gắng sử dụng cùng một mã để thêm hai trang tính mới, 'x3' và 'x4', thì dữ liệu gốc sẽ bị mất.

import pandas as pd
import numpy as np

path = r"C:\Users\fedel\Desktop\excelData\PhD_data.xlsx"

x3 = np.random.randn(100, 2)
df3 = pd.DataFrame(x3)

x4 = np.random.randn(100, 2)
df4 = pd.DataFrame(x4)

writer = pd.ExcelWriter(path, engine = 'xlsxwriter')
df3.to_excel(writer, sheet_name = 'x3')
df4.to_excel(writer, sheet_name = 'x4')
writer.save()
writer.close()

Tôi muốn một tệp excel có bốn trang tính: 'x1', 'x2', 'x3', 'x4'. Tôi biết rằng 'xlsxwriter' không phải là "động cơ" duy nhất, còn có 'openpyxl'. Tôi cũng đã thấy có những người khác đã viết về vấn đề này, nhưng tôi vẫn không thể hiểu làm thế nào để làm điều đó.

Đây là một đoạn mã được lấy từ liên kết này

import pandas
from openpyxl import load_workbook

book = load_workbook('Masterfile.xlsx')
writer = pandas.ExcelWriter('Masterfile.xlsx', engine='openpyxl') 
writer.book = book
writer.sheets = dict((ws.title, ws) for ws in book.worksheets)

data_filtered.to_excel(writer, "Main", cols=['Diff1', 'Diff2'])

writer.save()

Họ nói rằng nó hoạt động, nhưng thật khó để tìm ra cách. Tôi không hiểu "ws.title", "ws" và "dict" là gì trong ngữ cảnh này.

Cách tốt nhất để lưu "x1" và "x2", sau đó đóng tệp, mở lại và thêm "x3" và "x4"?

Câu trả lời:


118

Cảm ơn bạn. Tôi tin rằng một ví dụ hoàn chỉnh có thể tốt cho bất kỳ ai khác có cùng vấn đề:

import pandas as pd
import numpy as np

path = r"C:\Users\fedel\Desktop\excelData\PhD_data.xlsx"

x1 = np.random.randn(100, 2)
df1 = pd.DataFrame(x1)

x2 = np.random.randn(100, 2)
df2 = pd.DataFrame(x2)

writer = pd.ExcelWriter(path, engine = 'xlsxwriter')
df1.to_excel(writer, sheet_name = 'x1')
df2.to_excel(writer, sheet_name = 'x2')
writer.save()
writer.close()

Ở đây tôi tạo một tệp excel, theo hiểu biết của tôi, nó không thực sự quan trọng cho dù nó được tạo thông qua công cụ "xslxwriter" hay "openpyxl".

Khi tôi muốn viết mà không làm mất dữ liệu gốc thì

import pandas as pd
import numpy as np
from openpyxl import load_workbook

path = r"C:\Users\fedel\Desktop\excelData\PhD_data.xlsx"

book = load_workbook(path)
writer = pd.ExcelWriter(path, engine = 'openpyxl')
writer.book = book

x3 = np.random.randn(100, 2)
df3 = pd.DataFrame(x3)

x4 = np.random.randn(100, 2)
df4 = pd.DataFrame(x4)

df3.to_excel(writer, sheet_name = 'x3')
df4.to_excel(writer, sheet_name = 'x4')
writer.save()
writer.close()

mã này thực hiện công việc!


bất kỳ ý tưởng nào, tại sao khi tôi thử điều này, tôi nhận được: ValueError: Không có người viết Excel 'Tính toán doanh số bán hàng.xlsx'?
bernando_vialli

1
vâng, đây là thêm trang tính vào excel mà không xóa các trang tính đã có từ trước. Cảm ơn!
Nikhil VJ

2
Khi lưu tệp excel, Làm cách nào để giữ các định dạng trang tính excel hiện có?
Vineesh TP

3
Nếu bất cứ ai đọc này, phép lạ làm thế nào để ghi đè lên một tấm hiện có cùng tên thay vì đổi tên mới: Thêm dòng writer.sheets = dict((ws.title, ws) for ws in book.worksheets) sau writer.book = book
hại te sụp đổ

1
@Stefano Fedele bạn có thể cập nhật cùng một excel hiện có bằng cách sử dụng 'xlsxwriter' thay vì 'openpyxl' không?
M Nikesh

16

Trong ví dụ bạn đã chia sẻ, bạn đang tải tệp hiện có vào bookvà đặt writer.bookgiá trị là book. Trong dòng writer.sheets = dict((ws.title, ws) for ws in book.worksheets)bạn đang truy cập từng trang tính trong sổ làm việc với tư cách là ws. Khi đó, tiêu đề trang tính là wsdo bạn đang tạo một từ điển gồm {sheet_titles: sheet}các cặp khóa, giá trị. Từ điển này sau đó được đặt thành writer.sheets. Về cơ bản, các bước này chỉ là tải dữ liệu hiện có 'Masterfile.xlsx'và điền người viết của bạn vào chúng.

Bây giờ, giả sử bạn đã có một tệp với x1x2dưới dạng trang tính. Bạn có thể sử dụng mã ví dụ để tải tệp và sau đó có thể làm điều gì đó như thế này để thêm x3x4.

path = r"C:\Users\fedel\Desktop\excelData\PhD_data.xlsx"
writer = pd.ExcelWriter(path, engine='openpyxl')
df3.to_excel(writer, 'x3', index=False)
df4.to_excel(writer, 'x4', index=False)
writer.save()

Điều đó sẽ làm những gì bạn đang tìm kiếm.


bất kỳ ý tưởng nào, tại sao khi tôi thử điều này, tôi nhận được: ValueError: Không có người viết Excel 'Tính toán doanh số bán hàng.xlsx'?
bernando_vialli

18
điều này đang xóa các trang tính tồn tại trước đó.
Nikhil VJ

13

Một ví dụ đơn giản để ghi nhiều dữ liệu vào excel cùng một lúc. Và cả khi bạn muốn nối dữ liệu vào một trang tính trên tệp excel đã viết (tệp excel đóng).

Khi đây là lần đầu tiên bạn viết một excel. (Viết "df1" và "df2" thành "1st_sheet" và "2nd_sheet")

import pandas as pd 
from openpyxl import load_workbook

df1 = pd.DataFrame([[1],[1]], columns=['a'])
df2 = pd.DataFrame([[2],[2]], columns=['b'])
df3 = pd.DataFrame([[3],[3]], columns=['c'])

excel_dir = "my/excel/dir"

with pd.ExcelWriter(excel_dir, engine='xlsxwriter') as writer:    
    df1.to_excel(writer, '1st_sheet')   
    df2.to_excel(writer, '2nd_sheet')   
    writer.save()    

Sau khi bạn đóng excel của mình, nhưng bạn muốn "nối" dữ liệu trên cùng một tệp excel nhưng trên một trang tính khác, hãy nói "df3" vào tên trang tính "3_sheet".

book = load_workbook(excel_dir)
with pd.ExcelWriter(excel_dir, engine='openpyxl') as writer:
    writer.book = book
    writer.sheets = dict((ws.title, ws) for ws in book.worksheets)    

    ## Your dataframe to append. 
    df3.to_excel(writer, '3rd_sheet')  

    writer.save()     

Lưu ý rằng định dạng excel không được là xls, bạn có thể sử dụng xlsx.


1
Tôi không thấy câu trả lời này thêm gì. Trên thực tế, việc sử dụng lặp đi lặp lại một trình quản lý ngữ cảnh như thế này sẽ liên quan đến nhiều I / O hơn.
Charlie Clark

8

Tôi thực sự khuyên bạn nên làm việc trực tiếp với openpyxl vì nó hiện hỗ trợ Pandas DataFrames .

Điều này cho phép bạn tập trung vào mã Excel và mã Pandas có liên quan.


3
Sẽ thực sự hữu ích nếu bạn có thể thêm các ví dụ về "Gấu trúc" tương tự như thế này
MaxU 21/02/17

Bản thân tôi không làm nhiều việc với Pandas nên tôi không thể thực sự cung cấp nhiều ví dụ như vậy nhưng rất hoan nghênh những cải tiến cho tài liệu.
Charlie Clark

4

Để tạo một tệp mới

x1 = np.random.randn(100, 2)
df1 = pd.DataFrame(x1)
with pd.ExcelWriter('sample.xlsx') as writer:  
    df1.to_excel(writer, sheet_name='x1')

Để thêm vào tệp, hãy sử dụng đối số mode='a'trong pd.ExcelWriter.

x2 = np.random.randn(100, 2)
df2 = pd.DataFrame(x2)
with pd.ExcelWriter('sample.xlsx', engine='openpyxl', mode='a') as writer:  
    df2.to_excel(writer, sheet_name='x2')

Mặc định là mode ='w'. Xem tài liệu .


3

Có thể làm điều đó mà không cần sử dụng ExcelWriter, sử dụng các công cụ trong openpyxl Điều này có thể giúp việc thêm phông chữ vào trang tính mới dễ dàng hơn nhiều bằng cách sử dụng openpyxl.styles

import pandas as pd
from openpyxl import load_workbook
from openpyxl.utils.dataframe import dataframe_to_rows

#Location of original excel sheet
fileLocation =r'C:\workspace\data.xlsx'

#Location of new file which can be the same as original file
writeLocation=r'C:\workspace\dataNew.xlsx'

data = {'Name':['Tom','Paul','Jeremy'],'Age':[32,43,34],'Salary':[20000,34000,32000]}

#The dataframe you want to add
df = pd.DataFrame(data)

#Load existing sheet as it is
book = load_workbook(fileLocation)
#create a new sheet
sheet = book.create_sheet("Sheet Name")

#Load dataframe into new sheet
for row in dataframe_to_rows(df, index=False, header=True):
    sheet.append(row)

#Save the modified excel at desired location    
book.save(writeLocation)

Đây là một giải pháp tốt, tuy nhiên tôi không chắc liệu nó có phải là một ngụ ý hay không. Bạn có nghĩa là bạn không thể làm điều đó với ExcelWriterhoặc bạn chỉ cần không?
MattSom

Bạn có thể làm điều đó với Excelwriter, nhưng tôi thấy nó dễ dàng hơn khi chỉ sử dụng openpyxl.
Jis Mathew

2

Bạn có thể đọc các trang hiện có theo sở thích của mình, ví dụ: 'x1', 'x2', vào bộ nhớ và 'ghi' lại chúng trước khi thêm nhiều trang mới hơn (lưu ý rằng các trang trong một tệp và trang trong bộ nhớ là hai trang khác nhau những thứ, nếu bạn không đọc chúng, chúng sẽ bị mất). Cách tiếp cận này chỉ sử dụng 'xlsxwriter', không liên quan đến openpyxl.

import pandas as pd
import numpy as np

path = r"C:\Users\fedel\Desktop\excelData\PhD_data.xlsx"

# begin <== read selected sheets and write them back
df1 = pd.read_excel(path, sheet_name='x1', index_col=0) # or sheet_name=0
df2 = pd.read_excel(path, sheet_name='x2', index_col=0) # or sheet_name=1
writer = pd.ExcelWriter(path, engine='xlsxwriter')
df1.to_excel(writer, sheet_name='x1')
df2.to_excel(writer, sheet_name='x2')
# end ==>

# now create more new sheets
x3 = np.random.randn(100, 2)
df3 = pd.DataFrame(x3)

x4 = np.random.randn(100, 2)
df4 = pd.DataFrame(x4)

df3.to_excel(writer, sheet_name='x3')
df4.to_excel(writer, sheet_name='x4')
writer.save()
writer.close()

Nếu bạn muốn giữ lại tất cả các trang tính hiện có, bạn có thể thay thế mã trên giữa bắt đầu và kết thúc bằng:

# read all existing sheets and write them back
writer = pd.ExcelWriter(path, engine='xlsxwriter')
xlsx = pd.ExcelFile(path)
for sheet in xlsx.sheet_names:
    df = xlsx.parse(sheet_name=sheet, index_col=0)
    df.to_excel(writer, sheet_name=sheet)

1
#This program is to read from excel workbook to fetch only the URL domain names and write to the existing excel workbook in a different sheet..
#Developer - Nilesh K
import pandas as pd
from openpyxl import load_workbook #for writting to the existing workbook

df = pd.read_excel("urlsearch_test.xlsx")

#You can use the below for the relative path.
# r"C:\Users\xyz\Desktop\Python\

l = [] #To make a list in for loop

#begin
#loop starts here for fetching http from a string and iterate thru the entire sheet. You can have your own logic here.
for index, row in df.iterrows():
    try: 
        str = (row['TEXT']) #string to read and iterate
        y = (index)
        str_pos = str.index('http') #fetched the index position for http
        str_pos1 = str.index('/', str.index('/')+2) #fetched the second 3rd position of / starting from http
        str_op = str[str_pos:str_pos1] #Substring the domain name
        l.append(str_op) #append the list with domain names

    #Error handling to skip the error rows and continue.
    except ValueError:
            print('Error!')
print(l)
l = list(dict.fromkeys(l)) #Keep distinct values, you can comment this line to get all the values
df1 = pd.DataFrame(l,columns=['URL']) #Create dataframe using the list
#end

#Write using openpyxl so it can be written to same workbook
book = load_workbook('urlsearch_test.xlsx')
writer = pd.ExcelWriter('urlsearch_test.xlsx',engine = 'openpyxl')
writer.book = book
df1.to_excel(writer,sheet_name = 'Sheet3')
writer.save()
writer.close()

#The below can be used to write to a different workbook without using openpyxl
#df1.to_excel(r"C:\Users\xyz\Desktop\Python\urlsearch1_test.xlsx",index='false',sheet_name='sheet1')

2
Tôi không theo dõi điều này có liên quan như thế nào đến câu hỏi, ngoại trừ nó về excel.
Artog

Tôi đang làm việc để tìm ra giải pháp hoàn chỉnh để đọc và ghi vào sổ làm việc hiện có nhưng không thể tìm thấy giải pháp tương tự. Ở đây tôi đã tìm thấy một gợi ý về cách ghi vào sổ làm việc hiện có nên tôi đã nghĩ đến việc đưa ra một giải pháp hoàn chỉnh cho vấn đề của mình. Hy vọng nó rõ ràng.
nileshk611

0

Một cách khá đơn giản khác để thực hiện điều này là tạo một phương pháp như sau:

def _write_frame_to_new_sheet(path_to_file=None, sheet_name='sheet', data_frame=None):
    book = None
    try:
        book = load_workbook(path_to_file)
    except Exception:
        logging.debug('Creating new workbook at %s', path_to_file)
    with pd.ExcelWriter(path_to_file, engine='openpyxl') as writer:
        if book is not None:
            writer.book = book
        data_frame.to_excel(writer, sheet_name, index=False)

Ý tưởng ở đây là tải sổ làm việc tại path_to_file nếu nó tồn tại và sau đó nối data_frame dưới dạng một trang tính mới với sheet_name . Nếu sổ làm việc không tồn tại, nó sẽ được tạo. Dường như không phải openpyxl hoặc xlsxwriter append, vì vậy như trong ví dụ của @Stefano trên, bạn thực sự phải tải và sau đó viết lại để append.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.