Как переместить столбец в кадре данных панд - PullRequest
0 голосов
/ 03 октября 2018

Я хочу взять столбец с индексом '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, верно?

Кроме того, существует ли общий метод для перемещения любого столбца по метке в указанную позицию?Мои столбцы имеют только один уровень, т.е. MultiIndex не задействован.

1 Ответ

0 голосов
/ 03 октября 2018

Исправление вашей ошибки

Я не уверен, как интерпретировать эту ошибку, потому что она действительно должна быть списком, верно?

Нет: colnames[0] иcolnames[4] - это скаляры, а не списки.Вы не можете объединить скаляр со списком.Для составления списков используйте квадратные скобки:

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

Кроме того, я настоятельно рекомендую использовать df.columns = colnames вместо df[[colnames]]: __getitem__ (или его синтаксический сахар []) запускает операцию копирования .

Общее решение

Но преобразование массивов в списки и последующее объединение списков вручную не только дорого, но и подвержено ошибкам.Ответ, связанный с имеет много решений на основе списка, но решение на основе 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...