【问题标题】:Reshaping a pandas dataframe without a true index在没有真正索引的情况下重塑熊猫数据框
【发布时间】:2018-02-04 13:05:27
【问题描述】:

在过去的几周里,我一直在尝试构建回归输出的数据框,并且我已经完成了大部分工作。我现在正试图围绕列中的某些关键字对其进行重塑,据我所知,这些关键字是不可调用的。

我的数据框的简化版本如下所示:

?           coef pval  se   rsq
Intercept   1    0     .1   .1
Cash        2    0.2   .05  .1
Food        2    0.05  .2   .1
Intercept   3    0     .1   .2
Cash        1    0.01  .2   .2
Food        2    0.3   .1   .2
Zone        1    0.4   .3   .2

我想要实现的是:

                (1)      (2)
Intercept coef   1        3
Intercept pval   0        0
Intercept se     0.1      0.1
Cash coef        2        1
Cash pval        0.2      0.01
Cash se          0.05     0.2
Food coef        2        2
Food pval        0.05     0.3
Food se          0.2      0.1
Zone coef        NaN      1
Zone pval        NaN      0.4
Zone se          NaN      0.3
rsq              0.1      0.2

到目前为止,我已经尝试了几种方法,有希望使用 r-squared (rsq) 作为索引进行整形 -> RegTable = RegTable.pivot(index='rsq', columns=['pval', 'coef', 'robust_se'])

然而,这会返回错误ValueError: all arrays must be same length。一些研究让我认为这是因为截至目前,zone = NaN 由回归表示,根本没有区域行,但我不知道如何解决它。此外,我一直无法弄清楚如何调用我标识为“?”的列使用 PANDAS - 它没有在 CSV 输出中标记。此外,这种方法似乎存在问题,因为如果两个回归具有相同的 r 平方,它最终会抛出一个新的错误或平均每个值,这两者都不是完全可取的。

【问题讨论】:

    标签: python pandas dataframe statsmodels


    【解决方案1】:

    让我们试试这个:

    df.set_index(['rsq','?']).stack().unstack([0]).T\
      .reset_index().T.rename_axis([None,None])\
      .rename(columns={0:'(1)',1:'(2)'})\
      .sort_index()
    

    哪里df:

               ?  coef  pval    se  rsq
    0  Intercept     1  0.00  0.10  0.1
    1       Cash     2  0.20  0.05  0.1
    2       Food     2  0.05  0.20  0.1
    3  Intercept     3  0.00  0.10  0.2
    4       Cash     1  0.01  0.20  0.2
    5       Food     2  0.30  0.10  0.2
    6       Zone     1  0.40  0.30  0.2
    

    输出:

                     (1)   (2)
    Cash      coef  2.00  1.00
              pval  0.20  0.01
              se    0.05  0.20
    Food      coef  2.00  2.00
              pval  0.05  0.30
              se    0.20  0.10
    Intercept coef  1.00  3.00
              pval  0.00  0.00
              se    0.10  0.10
    Zone      coef   NaN  1.00
              pval   NaN  0.40
              se     NaN  0.30
    rsq             0.10  0.20
    

    【讨论】:

    • 很好,但你忘记了最后的 rsq 行。
    • 最上面一行。我想我可以排序。
    • 哦,非易失性。没看到。
    • @cᴏʟᴅsᴘᴇᴇᴅ 好的,我整理好了。 :)
    • 是的,我花了一段时间才想出答案。可惜这个问题没有引起任何关注。 +1
    【解决方案2】:

    这个解决方案背后的直觉是将数据帧分成两个大致相等的部分。这里的假设是您只有两组数据点,因此这变得易于管理。

    print(df)
    
               coef  pval    se  rsq
    Intercept     1  0.00  0.10  0.1
    Cash          2  0.20  0.05  0.1
    Food          2  0.05  0.20  0.1
    Intercept     3  0.00  0.10  0.2
    Cash          1  0.01  0.20  0.2
    Food          2  0.30  0.10  0.2
    Zone          1  0.40  0.30  0.2
    
    
    df_ = df.reset_index().iloc[:, :-1]
    
    df2 = df_.iloc[df_['index'].drop_duplicates(keep='first').to_frame().index]
    df1 = df_.iloc[df_['index'].drop_duplicates(keep='last')\
                     .to_frame().index.difference(df2.index)]
    

    完成此操作后,每个部分都必须堆叠,然后沿第一个轴连接。

    out = pd.concat([df1.set_index('index').stack(),\
                     df2.set_index('index').stack()], 1)
    out.append(pd.DataFrame([df.rsq.unique()], index=[('rsq', '')]))
    out.columns = ['1', '2']
    
    print(out) 
    
                       1     2
    index                     
    Cash      coef  1.00  2.00
              pval  0.01  0.20
              se    0.20  0.05
    Food      coef  2.00  2.00
              pval  0.30  0.05
              se    0.10  0.20
    Intercept coef  3.00  1.00
              pval  0.00  0.00
              se    0.10  0.10
    Zone      coef   NaN  1.00
              pval   NaN  0.40
              se     NaN  0.30
    rsq             0.10  0.20
    

    【讨论】:

      【解决方案3】:

      这是一种稍微古怪的方法,无需拆分为两个数据帧。

      此解决方案重命名索引以跟踪它们所属的回归,当缺少字段时添加 NaN(如 Zone 的情况)。
      然后groupbystack,并将列表列拆分为(1)(2) 列(尽管它被概括为处理数据中出现的尽可能多的回归)。

      df 为:

                  coef pval  se   rsq
      Intercept   1    0     .1   .1
      Cash        2    0.2   .05  .1
      Food        2    0.05  .2   .1
      Intercept   3    0     .1   .2
      Cash        1    0.01  .2   .2
      Food        2    0.3   .1   .2
      Zone        1    0.4   .3   .2
      

      将索引值重命名为Intercept0Intercept1 等:

      measures = df.index.unique()
      found = {m:0 for m in measures}
      
      for i, name in enumerate(df.index):
          if np.max(list(found.values())) > found[name]+1:
              df.loc["{}{}".format(name, found[name])] = np.nan
              found[name] += 1
          df.index.values[i] = "{}{}".format(name, found[name])
          found[name] += 1
      
      df
                  coef  pval    se  rsq
      Intercept0   1.0  0.00  0.10  0.1
      Cash0        2.0  0.20  0.05  0.1
      Food0        2.0  0.05  0.20  0.1
      Intercept1   3.0  0.00  0.10  0.2
      Cash1        1.0  0.01  0.20  0.2
      Food1        2.0  0.30  0.10  0.2
      Zone1        1.0  0.40  0.30  0.2
      Zone0        NaN   NaN   NaN  NaN
      

      现在排列行,以便将来自每个回归的元素组合在一起。 (这主要是为了将NaN 行放在正确的位置。)

      order_by_reg = sorted(df.index, key=lambda x: ''.join(reversed(x)))
      df = df.loc[order_by_reg]
      
      df
                  coef  pval    se  rsq
      Food0        2.0  0.05  0.20  0.1
      Zone0        NaN   NaN   NaN  NaN
      Cash0        2.0  0.20  0.05  0.1
      Intercept0   1.0  0.00  0.10  0.1
      Food1        2.0  0.30  0.10  0.2
      Zone1        1.0  0.40  0.30  0.2
      Cash1        1.0  0.01  0.20  0.2
      Intercept1   3.0  0.00  0.10  0.2
      

      最后,groupbystack,并用apply(pd.Series)拆分列表的结果列:

      gb = (df.groupby(lambda x: x[:-1])
              .agg(lambda x: list(x))
              .stack()
              .apply(lambda pair: pd.Series({"({})".format(i):el for i, el in enumerate(pair)})))
      
      gb
                       (0)   (1)
      Cash      coef  2.00  1.00
                pval  0.20  0.01
                se    0.05  0.20
                rsq   0.10  0.20
      Food      coef  2.00  2.00
                pval  0.05  0.30
                se    0.20  0.10
                rsq   0.10  0.20
      Intercept coef  1.00  3.00
                pval  0.00  0.00
                se    0.10  0.10
                rsq   0.10  0.20
      Zone      coef   NaN  1.00
                pval   NaN  0.40
                se     NaN  0.30
                rsq    NaN  0.20
      

      【讨论】:

        猜你喜欢
        • 2017-12-14
        • 1970-01-01
        • 2017-08-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-30
        相关资源
        最近更新 更多