【问题标题】:Create pandas dataframe from series with ordered dict as rows从以有序字典为行的系列创建熊猫数据框
【发布时间】:2020-04-13 09:08:08
【问题描述】:

我正在尝试将lmfit 参数结果提取为数据框。我通过fit_func 和参数pars 传递1 列x,1 列datalmfitminimize 函数的输出输出为OrderedDict。

out = minimize(fit_func, pars, method = 'leastsq', args=(x, data))
res = out.params.valuesdict()
res

输出:

OrderedDict([('a1', 12.850309404600393),
             ('c1', 1346.833513206811),
             ('s1', 44.22337472274829),
             ('f1', 1.1275639898142586),
             ('a2', 77.15732669480884),
             ('c2', 1580.5712512351947),
             ('s2', 16.239969775527275),
             ('f2', 0.8684363668111492)])

我想要在 DataFrames 中使用 pd.DataFrame(res,index=[0]) 实现的输出:

我想快速适应 3 个数据列:

x = d.iloc[:,0]
fit_odict = pd.DataFrame(d.iloc[:,1:4].\
                         apply(lambda y: minimize(fit_func, pars, method = 'leastsq', args=(x, y))\
                        .params.valuesdict()),index=[1])

但我在数据框中得到了一系列有序字典:

如何将三个参数结果作为行来获得我想要的输出?有没有更好的方法来应用这个函数?

更新:

在我的解决方案中附加了@M Newville。对于想要从多个数据列d1.iloc[:,1:]快速提取lmfit参数结果的人可能会有所帮助:

def fff(cols):
    out = minimize(fit_func, pars, method = 'leastsq', args=(x, cols))
    return {key: par.value for key, par in out.params.items()}

results = d1.iloc[:,1:].apply(fff,result_type='expand').transpose()

输出:

【问题讨论】:

    标签: pandas dataframe series ordereddictionary lmfit


    【解决方案1】:

    这是您可以做的快速解决方法。该代码效率不高,但您可以对其进行优化。请注意,索引从 1 开始,但欢迎您使用 pandas 库重新索引

    import pandas as pd
    
    # Your output is a list of tuple
    OrderedDict = [('a1', 12.850309404600393),('c1', 1346.833513206811),('s1', 
    44.22337472274829),('f1', 1.1275639898142586),('a2', 77.15732669480884),('c2', 
    1580.5712512351947),('s2', 16.239969775527275),('f2', 0.8684363668111492)]
    
    # Create a dataframe from the list of tuple and tanspose
    df = pd.DataFrame(OrderedDict).T
    # Get the first row for the dataframe columns namea
    columns = df.loc[0].values.tolist()
    df.columns = columns
    output = df.drop(df.index[0])
    output
    
        a1      c1      s1      f1      a2      c2      s2      f2
    1   12.8503 1346.83 44.2234 1.12756 77.1573 1580.57 16.24   0.868436
    

    【讨论】:

      【解决方案2】:

      对于单一的合身,这可能就是您正在寻找的:

      out = minimize(fit_func, pars, method = 'leastsq', args=(x, data))
      fit_odict = pd.DataFrame({key: [par.value] for key, par in out.params.items()})
      

      我想你可能正在寻找这样的东西:

      results = {key: [] for key in pars}
      for data in datasets:
          out = minimize(fit_func, pars, method='leastsq', args=(x, data))
          for par_name, val_list in results.items():
              val_list.append(out.params[par_name].value)
      results = pd.DataFrame(results)
      

      您可能会将所有内容都塞进一条长行中,但我不建议这样做——有人可能想阅读该代码;)。

      【讨论】:

      • 嗨!这对我有用!但是计算 400 datasets 列确实需要很长时间(假设它是嵌套的 for 循环)。会有更快的方法来执行此操作吗?我可能不清楚 400 个要拟合的列已经在 pandas 数据框中。
      • @Hud 原则上,您可以并行执行 400 次。单个拟合本身无法轻松并行化,但您可以使用多处理模块在单独的进程和单独的 CPU 内核上执行每个拟合。您可能没有 400 个内核,但一次工作 4 或 8 个内核也会有所帮助。 FWIW,实际拟合将占用所有实际运行时间,因此数据是在 pandas 数据帧还是 numpy 数组中都没关系。
      猜你喜欢
      • 2018-02-26
      • 1970-01-01
      • 1970-01-01
      • 2016-01-14
      • 2014-11-22
      • 1970-01-01
      • 1970-01-01
      • 2020-08-14
      相关资源
      最近更新 更多