Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/351.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在数据帧中移动列_Python_Pandas_Numpy_Dataframe_Indexing - Fatal编程技术网

Python 如何在数据帧中移动列

Python 如何在数据帧中移动列,python,pandas,numpy,dataframe,indexing,Python,Pandas,Numpy,Dataframe,Indexing,我想将一列索引为“length”,并使其成为我的第二列。它目前作为第5列存在。我试过: colnames = big_df.columns.tolist() # make index "length" the second column in the big_df colnames = colnames[0] + colnames[4] + colnames[:-1] big_df = big_df[colnames] 我看到以下错误: TypeError:必须是str,而不是list

我想将一列索引为“length”,并使其成为我的第二列。它目前作为第5列存在。我试过:

colnames = big_df.columns.tolist()

# make index "length" the second column in the big_df
colnames = colnames[0] + colnames[4] + colnames[:-1] 

big_df = big_df[colnames]
我看到以下错误:

TypeError:必须是str,而不是list

我不确定如何解释这个错误,因为它实际上应该是一个
列表,对吗

此外,是否有一种通用方法可以按标签将任何列移动到指定位置?我的列只有一个级别,即不涉及多索引。

更正错误 我不知道如何解释这个错误,因为它实际上应该是 一份清单,对吗

否:
colnames[0]
colnames[4]
是标量,而不是列表。不能将标量与列表连接起来。要将它们列为列表,请使用方括号:

colnames = [colnames[0]] + [colnames[4]] + colnames[:-1]
您可以使用
df[[colnames]]
df.reindex(columns=colnames)
:这两种方法都是复制操作,因为无法就地处理此转换

通解 但是,将数组转换为列表,然后手动连接列表不仅成本高昂,而且容易出错。A有许多基于列表的解决方案,但是基于NumPy的解决方案是值得的,因为
pd.Index
对象存储为NumPy数组

这里的关键是通过切片而不是串联来修改NumPy数组。只有两种情况需要处理:当前位置之后存在所需位置,反之亦然

import pandas as pd, numpy as np
from string import ascii_uppercase

df = pd.DataFrame(columns=list(ascii_uppercase))

def shifter(df, col_to_shift, pos_to_move):
    arr = df.columns.values
    idx = df.columns.get_loc(col_to_shift)
    if idx == pos_to_move:
        pass
    elif idx > pos_to_move:
        arr[pos_to_move+1: idx+1] = arr[pos_to_move: idx]
    else:
        arr[idx: pos_to_move] = arr[idx+1: pos_to_move+1]
    arr[pos_to_move] = col_to_shift
    df = df.reindex(columns=arr)
    return df
    
df = df.pipe(shifter, 'J', 1)

print(df.columns)

Index(['A', 'J', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'K', 'L', 'M', 'N',
       'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'],
      dtype='object')
绩效基准 与基于列表的方法相比,使用NumPy切片处理大量列更有效:

n = 10000
df = pd.DataFrame(columns=list(range(n)))

def shifter2(df, col_to_shift, pos_to_move):
    cols = df.columns.tolist()
    cols.insert(pos_to_move, cols.pop(df.columns.get_loc(col_to_shift)))
    df = df.reindex(columns=cols)
    return df

%timeit df.pipe(shifter, 590, 5)   # 381 µs
%timeit df.pipe(shifter2, 590, 5)  # 1.92 ms

更一般地说,移动列来组织数据帧的最佳实践是什么?可能是重复的,但总而言之,似乎缺少一些方括号;尝试使用
big_df=big_df[[colnames]]]
我强烈建议您使用
df.columns=colnames
而不是
df[[colnames]]]
作为
\uu getitem\uuuu
。但这是微不足道的一点。我还没有看到任何好的基于NumPy的解决方案。