微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

python – 如何在pandas数据帧中移动列

我想把一个索引为’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: must be str, not list

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

另外,是否有通用方法将任何列按标签移动到指定位置?我的列只有一个级别,即没有涉及MultiIndex.

解决方法:

纠正错误

I’m not sure how to interpret this error because it actually should be
a list, right?

No:colnames [0]和colnames [4]是标量,而不是列表.您无法将标量与列表连接起来.要使它们成为列表,请使用方括号:

colnames = [colnames[0]] + [colnames[4]] + colnames[:-1]

另外,我强烈建议你使用df.columns = colnames而不是df [[colnames]]:__ getitem __(或其语法糖[])triggers a copy operation.

通用解决方

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

这里的关键是通过切片而不是连接来修改NumPy数组.只处理2种情况:当前位置后存在所需位置时,反之亦然.

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.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.columns = cols
    return df

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐