在Excel中结合excel表单和pandas

所以,我在python中使用这个脚本来做一些事情。 它:将两个Excel表单合并在一起,并创build一个新的表单,并为这些表单添加另一列,以显示原始文件的来源。 这是脚本:

import pandas as pd import numpy as np import os from os.path import basename df = [] #enter your file names via terminal file1 = raw_input("Enter the path to the first file):") file2 = raw_input("Enter the path to the second file):") for f in [file1, file2]: data = pd.read_excel(f, 'Sheet1') data.index = [os.path.basename(f)] * len(data) df.append(data) #add the column that includes the original file data.index = [basename(f)] * len(data) #set the path and name of your final product file final = raw_input('Where do you want the file, and what do you want to name it? (C:\path_to_file\name_of_file.xlsx):') df = pd.concat(df) df.to_excel(final) 

现在,我的问题是,让我们说,我们结合了两个Excel文件,看起来像这样:

  Item Inv Price Sold dbtest1.xlsx Banana 50 1 27 dbtest1.xlsx Grapes 100 3 68 dbtest2.xlsx Oranges 68 3 17 dbtest2.xlsx Apples 22 1.5 9 dbtest2.xlsx Strawberries 245 4 122 

我想把这个excel文件,现在称为dbtestfinal.xlsx到另一个excel文件。 我得到的结果是:

  Item Inventory Price Sold dbtest3.xlsx Pork 49 2.99 47 dbtest3.xlsx Beef 27 1.5 78 dbtest3.xlsx Chicken 245 1.99 247 dbtestfinal.xlsx Banana 50 1 27 dbtestfinal.xlsx Grapes 100 3 68 dbtestfinal.xlsx Oranges 68 3 17 dbtestfinal.xlsx Apples 22 1.5 9 dbtestfinal.xlsx Stra... 245 4 122 

我希望它能够保持它来自的原始文件,所以而不是只有dbtest3.xlsxdbtestfinal.xlsx ,它将有dbtest1 。 有没有办法让它做这样的事情?

另外,在文件添加date的列中添加也会很棒!

最后一个补充,这个可能不是微不足道的:有没有办法让程序检测到相同的文件来源,并用新的替代? 所以,如果你编辑dbtest2.xlsx和增加/减less的项目,程序会删除旧的,只input这个新的文件?

谢谢你的任何build议!

考虑这个调整后的脚本。 在附加到列表之前,此脚本导入到单独的数据框,然后再连接它们。 至于你的命名dbtest1, 2, 3只需要在CPU目录中命名这些文件,脚本会相应地索引这些文件。

另外,在执行脚本后没有任何内容保存在内存中,因此只需重新导入一个较早的输出文件,以进一步将其他工作表dataframe连接到一个“运行”附加dataframe中。 此外,脚本导入Excel文件的当前状态,所以最新的数据。

最后,我添加了一些validation和尝试/除了处理,因为脚本的大部分依赖于用户input,应该在处理之前检查。 我甚至添加了一个输出工作表的自动打开文件的成功消息。

 import subprocess import pandas as pd import numpy as np import os, sys from os.path import basename # CSV IMPORT DEFINED FUNCTION def csvImport(ftype, fpath): try: if ftype == 1: masterdata = pd.read_csv(fpath) return masterdata if ftype == 2: updateddata = pd.read_csv(fpath) updateddata['originfile'] = pd.Series(os.path.basename(fpath), \ index=updateddata.index) return updateddata except Exception as e: print "\nUnable to import CSV file. Error {}".format(e) sys.exit(1) # EXCEL IMPORT DEFINED FUNCTION def xlImport(ftype, fpath): try: if ftype == 1: masterdata = pd.read_excel(fpath, 0) return masterdata if ftype == 2: updateddata = pd.read_excel(fpath, 0) updateddata['orginfile'] = pd.Series(os.path.basename(fpath), \ index=updateddata.index) return updateddata except Exception as e: print "\nUnable to import Excel file. Error {}".format(e) sys.exit(1) # MASTER FILE USER INPUT DEFINED FUNCTION def masterfile(): while True: masterfile = raw_input("Enter the path to the master file: ") if masterfile.endswith(".csv"): return csvImport(1, masterfile) break elif masterfile.endswith(".xlsx"): return xlImport(1, masterfile) break else: print "\nPlease enter a proper CSV format file." # UPDATED FILE USER INPUT DEFINED FUNCTION def updatefile(): while True: updatedfile = raw_input("\nEnter the path to the updated file: ") if updatedfile.endswith(".csv"): return csvImport(2, updatedfile) break elif updatedfile.endswith(".xlsx"): return xlImport(2, updatedfile) break else: print "\nPlease enter a proper Excel file in xlsx format." # CALLING OPENING FUNCTIONS masterdata = masterfile() updateddata = updatefile() # CONCATENATING DATA FRAMES combineddata = pd.concat([updateddata, masterdata]) # REMOVING DUPLICATES finaldata = combineddata.drop_duplicates(['Item']) # SETTING FINAL PATH BY USER INPUT while True: final = raw_input("\nWhere do you want the file, and what do you want to name it? \ (eg, C:\path_to_file\name_of_file.xlsx): ") if final.endswith(".xlsx"): break else: print "\nPlease enter a proper Excel file in xlsx format." # OUTPUTTING DATA FRAME TO FILE finaldata.to_excel(final) print "\nSuccessfully outputted appended data frame to Excel!" # OPENING OUTPUTTED FILE # (NOTE: PYTHON STILL RUNS UNTIL SPREADSHEET IS CLOSED) subprocess.call(final, shell=True)