如何使用数据框创建具有不确定长度的Excel电子表格?

时间:2017-06-20 13:15:32

标签: python excel pandas dataframe

我是python的新用户,我一直在编写一个程序,我需要创建一个包含不确定列数的excel电子表格。所以我之前创建4列的代码是:

writer = pd.ExcelWriter(datapath + 'Test#' + str(testcount) + '.xlsx', engine = 'xlsxwriter')
df1 = pd.DataFrame({'Species 1' : evolution[0]})
df2 = pd.DataFrame({'Species 2' : evolution[1]})
df3 = pd.DataFrame({'Species 3' : evolution[2]})
df4 = pd.DataFrame({'Species 4' : evolution[3]})
df1.to_excel(writer, sheet_name='Raw Data')
df2.to_excel(writer, sheet_name='Raw Data', startcol=2, index=False)
df3.to_excel(writer, sheet_name='Raw Data', startcol=3, index=False)
df4.to_excel(writer, sheet_name='Raw Data', startcol=4, index=False)
writer.save()

(Evolution是一个单独的函数,我从中绘制数据以填充列。)因此上面的代码完全按照需要工作。我尝试创建一种具有不确定数量的列的方法是这样的:

writer = pd.ExcelWriter(datapath + 'Test#' + str(testcount) + '.xlsx', engine = 'xlsxwriter')
def do(x):
    and1 = x+1
    "df" + str(and1) = pd.DataFrame({"Species " + str(i) : evolution[x]})
def do2(x):
    and1 = x+1
    "df" + str(and1).to_excel(writer, sheet_name='Raw Data', startcol=and1, index=False)
def repeat(times, f):
    for i in range(times): f()

repeat(colnumb, do)
repeat(colnumb, do2)
writer.save()

(" colnumb"是一个预定义的变量。)但是,这会继续输出以下错误:

"df" + str(and1) = pd.DataFrame({"Species " + str(i) : evolution[x]})
^
SyntaxError: can't assign to operator

如果有人能帮我看看我尝试过的解决方案有什么问题,或者澄清更好的方法来实现我的目标,我将非常感激。 (如果我弄乱了任何格式,也很抱歉。这是我第一次在这里发帖提问,所以如果我搞了一些约定请告诉我。)

2 个答案:

答案 0 :(得分:1)

您只需创建一个包含所有列的数据框并将其导出:

data = {'Species 1' : evolution[0], 'Species 2' : evolution[1], 'Species 3' : evolution[2], 'Species 4' : evolution[3]}

writer = pd.ExcelWriter(datapath + 'Test#' + str(testcount) + '.xlsx', engine = 'xlsxwriter')
df = pd.DataFrame(data)
df.to_excel(writer, sheet_name='Raw Data')
writer.save()

这是你的问题吗?

答案 1 :(得分:0)

我认为你过度设计了这个。您获得的语法错误是因为您正在尝试创建动态变量名来存储每个数据帧,但您无法在表达式中存储值(即str(and1)无法保存pd.DataFrame({"Species " + str(i) : evolution[x-1]})返回的值。 ,这个操作是不必要的,所以让我们看一下代码的其余部分。

首先,您可以将所有函数组合到一个迭代中,这样您只需迭代一次列,然后对该列执行所有必要的操作。这最好通过词典理解来完成。其次,您似乎正在使用DataFrames来保存Series对象。实际上,您可以在将整个数据框完整地导出到Excel之前先创建它。

您在repeat()调用中调用colnumb变量,但我不确定它来自何处,因为您尚未创建任何包含列的数据帧。是evolution的长度吗?此外,您调用evolution函数,但与存储先前运行函数的结果的列表进行交互。我将为这两种方案提供解决方案。一个更简单,更高效的版本看起来像:

  1. 如果colnumb是您输入的任意数字

    # Create a dictionary with all columns of dynamic Species names storing the relevant value of evolution.
    species_dict = {'Species {}'.format(i) : [evolution[i]] for i in range(colnumb)}
    
    # Turn that dict into a dataframe
    df = pd.DataFrame(species_dict)
    
    # Output the dataframe to Excel
    df.to_excel(datapath + 'Test#' + str(testcount) + 'xlsx', 'Raw Data')
    
  2. 如果colnumb真的只是进化的长度:

    # Create dict by enumerating all values of evolution to access both index and value
    species_dict = {'Species {}'.format(i): [value] for i, value in evolution.items()}
    
    # Convert dict to dataframe
    df = pd.DataFrame(species_dict)
    
    # Output the dataframe to Excel
    df.to_excel(datapath + 'Test#' + str(testcount) + 'xlsx', 'Raw Data')