【问题标题】:How to rearrange Pandas column sequence?如何重新排列 Pandas 列序列?
【发布时间】:2012-09-02 00:44:18
【问题描述】:
>>> df =DataFrame({'a':[1,2,3,4],'b':[2,4,6,8]})
>>> df['x']=df.a + df.b
>>> df['y']=df.a - df.b
>>> df
   a  b   x  y
0  1  2   3 -1
1  2  4   6 -2
2  3  6   9 -3
3  4  8  12 -4

现在我想重新排列列序列,使 'x','y' 列成为第一列和第二列:

>>> df = df[['x','y','a','b']]
>>> df
    x  y  a  b
0   3 -1  1  2
1   6 -2  2  4
2   9 -3  3  6
3  12 -4  4  8

但是,如果我有一个很长的 'a'、'b'、'c'、'd'......,并且我不想明确列出这些列。我该怎么做?

或者 Pandas 是否提供像 set_column_sequence(dataframe,col_name, seq) 这样的功能以便我可以做到:set_column_sequence(df,'x',0)set_column_sequence(df,'y',1)

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    你也可以这样做:

    df = df[['x', 'y', 'a', 'b']]
    

    您可以通过以下方式获取列列表:

    cols = list(df.columns.values)
    

    输出将产生如下内容:

    ['a', 'b', 'x', 'y']
    

    ...然后很容易在将其放入第一个函数之前手动重新排列

    【讨论】:

    • 对于像我这样的新手,重新排列您从cols 获得的list。然后df=df[cols] 即重新排列的列表被放入第一个表达式中,没有一组括号。
    • 你能解释一下第一个例子吗?
    【解决方案2】:

    可能有一个优雅的内置函数(但我还没有找到)。你可以写一个:

    # reorder columns
    def set_column_sequence(dataframe, seq, front=True):
        '''Takes a dataframe and a subsequence of its columns,
           returns dataframe with seq as first columns if "front" is True,
           and seq as last columns if "front" is False.
        '''
        cols = seq[:] # copy so we don't mutate seq
        for x in dataframe.columns:
            if x not in cols:
                if front: #we want "seq" to be in the front
                    #so append current column to the end of the list
                    cols.append(x)
                else:
                    #we want "seq" to be last, so insert this
                    #column in the front of the new column list
                    #"cols" we are building:
                    cols.insert(0, x)
    return dataframe[cols]
    

    对于您的示例:set_column_sequence(df, ['x','y']) 将返回所需的输出。

    如果您想在 DataFrame 的 end 处添加 seq,只需传入“front=False”即可。

    【讨论】:

    • 希望我能找到 Pandas 内置的 'set_column_sequence(df, col_list, assign_col_seq)' 函数,我可以使用 "set_column_sequence(df,['x','y'],[0, 1])" 完成工作。
    • @bigbug 希望如此!如果我找到一个,我会更新我的答案......直到你这样做,这应该有效。
    • 加入一个列表理解版本来加快速度怎么样?
    • @pylang 我认为这不会加快速度(这不是我不应该认为的主要性能问题),但编写它的一种简洁方式是:s = {col: i for i, col in enumerate(first_cols)}; sorted(df.columns, key=lambda c: s.get(c, len(s)))。这仍然(4 年后)写起来有点尴尬,我虽然也许 sort_index 有一个技巧,但似乎没有。嗯
    • @pylang 可能你可以这样做:df[df.columns[df.columns.map(lambda col: s.get(col, len(s))).argsort()]] 但这很丑陋。仍然比这个旧答案更好,所以我可以在...中编辑它
    【解决方案3】:

    您可以执行以下操作:

    df =DataFrame({'a':[1,2,3,4],'b':[2,4,6,8]})
    
    df['x']=df.a + df.b
    df['y']=df.a - df.b
    

    以这种方式按您想要的顺序创建列标题:

    column_titles = ['x','y','a','b']
    
    df.reindex(columns=column_titles)
    

    这将为您提供所需的输出

    【讨论】:

    • 我的首选方式,因为这可以与数据帧上的其他方法链接
    【解决方案4】:
    def _col_seq_set(df, col_list, seq_list):
        ''' set dataframe 'df' col_list's sequence by seq_list '''
        col_not_in_col_list = [x for x in list(df.columns) if x not in col_list]
        for i in range(len(col_list)):
            col_not_in_col_list.insert(seq_list[i], col_list[i])
    
        return df[col_not_in_col_list]
    DataFrame.col_seq_set = _col_seq_set
    

    【讨论】:

      【解决方案5】:

      我建议您只编写一个函数来执行您所说的操作,可能使用drop(删除列)和insert 在某个位置插入列。没有现有的 API 函数可以执行您所描述的操作。

      【讨论】:

        【解决方案6】:

        请随意忽略此解决方案,因为从索引中减去列表不会保留原始索引的顺序,如果这很重要的话。

        In [61]: df.reindex(columns=pd.Index(['x', 'y']).append(df.columns - ['x', 'y']))
        Out[61]: 
            x  y  a  b
        0   3 -1  1  2
        1   6 -2  2  4
        2   9 -3  3  6
        3  12 -4  4  8
        

        【讨论】:

          猜你喜欢
          • 2021-12-26
          • 2021-09-30
          • 2020-06-15
          • 1970-01-01
          • 2019-03-26
          • 2019-02-02
          • 2021-12-23
          • 2018-10-28
          • 1970-01-01
          相关资源
          最近更新 更多