【问题标题】:In pandas, how to re-arrange the dataframe to simultaneously combine groups of columns?在熊猫中,如何重新排列数据框以同时组合列组?
【发布时间】:2020-11-03 07:45:21
【问题描述】:

我希望有人可以帮助我解决我的问题。

给定一个如下图所示的 pandas 数据框,

我想将它重新排列到一个新的数据框中,合并几组列(这些组的大小都相同),这样每组都变成一个列,如下面的所需结果图像所示。

提前感谢您的任何提示。

【问题讨论】:

    标签: python pandas dataframe concat


    【解决方案1】:

    对于通用解决方案,您可以尝试以下两个选项之一:

    您可以试试这个,使用OrderedDict 获取按字母顺序排列的字母非数字列名称,pd.DataFrame.filter 过滤具有相似名称的列,然后使用pd.DataFrame.stack 连接值:

    import pandas as pd
    from collections import OrderedDict
    
    df = pd.DataFrame([[0,1,2,3,4],[5,6,7,8,9]], columns=['a1','a2','b1','b2','c'])
    
    
    newdf=pd.DataFrame()
    
    for col in list(OrderedDict.fromkeys( ''.join(df.columns)).keys()):
        if col.isalpha():
            newdf[col]=df.filter(like=col, axis=1).stack().reset_index(level=1,drop=True)
    newdf=newdf.reset_index(drop=True)
    

    输出:

    df
       a1  a2  b1  b2  c
    0   0   1   2   3  4
    1   5   6   7   8  9
    
    newdf
       a  b  c
    0  0  2  4
    1  1  3  4
    2  5  7  9
    3  6  8  9
    

    另一种获取列名的方法是像这样使用reset,然后按字母顺序对列进行排序:

    newdf=pd.DataFrame()
    import re
    for col in set(re.findall('[^\W\d_]',''.join(df.columns))):
        newdf[col]=df.filter(like=col, axis=1).stack().reset_index(level=1,drop=True)
    newdf=newdf.reindex(sorted(newdf.columns), axis=1).reset_index(drop=True)
    

    输出:

    newdf
       a  b  c
    0  0  2  4
    1  1  3  4
    2  5  7  9
    3  6  8  9
    

    【讨论】:

      【解决方案2】:

      您可以使用 pd.wide_to_longrename 'c' 列来做到这一点:

      df_out = pd.wide_to_long(df.reset_index().rename(columns={'c':'c1'}),
                               ['a','b','c'],'index','no')
      df_out = df_out.reset_index(drop=True).ffill().astype(int)
      df_out
      

      输出:

         a  b  c
      0  0  2  4
      1  1  3  4
      2  5  7  9
      3  6  8  9
      

      相同的数据框只是排序不同。

      pd.wide_to_long(df,  ['a','b'], 'c', 'no').reset_index().drop('no', axis=1)
      

      输出:

         c  a  b
      0  4  0  2
      1  9  5  7
      2  4  1  3
      3  9  6  8
      

      【讨论】:

      • 谢谢你,Scott,你无法想象你为我节省了多少时间。祝你有美好的一天。
      【解决方案3】:

      c 列只有一列,而其他字母有两列,这一事实使它有点棘手。我首先堆叠了数据框并去掉了列名中的数字。然后对于 a 和 b,我旋转了一个数据框并删除了所有 nans。对于 c,我将数据帧的长度乘以 2 以使其匹配 a 和 b,然后将其与 a 和 b 合并。

      输入:

      import pandas as pd
      df = pd.DataFrame({'a1': {0: 0, 1: 5},
       'a2': {0: 1, 1: 6},
       'b1': {0: 2, 1: 7},
       'b2': {0: 3, 1: 8},
       'c': {0: 4, 1: 9}})
      df
      

      代码:

      df1=df.copy().stack().reset_index().replace('[0-9]+', '', regex=True)
      dfab = df1[df1['level_1'].isin(['a','b'])].pivot(index=0, columns='level_1', values=0) \
                               .apply(lambda x: pd.Series(x.dropna().values)).astype(int)
      dfc = pd.DataFrame(np.repeat(df['c'].values,2,axis=0)).rename({0:'c'}, axis=1)
      df2=pd.merge(dfab, dfc, how='left', left_index=True, right_index=True)
      df2
      

      输出:

          a   b   c
      0   0   2   4
      1   1   3   4
      2   5   7   9
      3   6   8   9
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-06-13
        • 2019-07-09
        • 1970-01-01
        • 1970-01-01
        • 2017-02-07
        • 2020-04-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多