Одна линия или трубопроводные решения
Я сосредоточусь на двух вещах:
ОП четко заявляет
У меня есть отредактированные имена столбцов, которые хранятся в списке, но я не знаю, как заменить имена столбцов.
Я не хочу решать проблему замены '$'
или удаления первого символа каждого заголовка столбца. ОП уже сделал этот шаг. Вместо этого я хочу сосредоточиться на замене существующего columns
объекта новым, учитывая список имен замещающих столбцов.
df.columns = new
где new
список имен новых столбцов так же прост, как и получается. Недостаток этого подхода заключается в том, что он требует редактирования columns
атрибута существующего информационного кадра, и он не выполняется встраиваемым образом. Я покажу несколько способов сделать это с помощью конвейерной обработки, не редактируя существующий фрейм данных.
Настройка 1
Чтобы сосредоточиться на необходимости переименования заменяемых имен столбцов в уже существующий список, я создам новый примерный кадр данных df
с исходными именами столбцов и несвязанными новыми именами столбцов.
df = pd.DataFrame({'Jack': [1, 2], 'Mahesh': [3, 4], 'Xin': [5, 6]})
new = ['x098', 'y765', 'z432']
df
Jack Mahesh Xin
0 1 3 5
1 2 4 6
Решение 1
pd.DataFrame.rename
Уже говорилось, что если бы у вас был словарь, сопоставляющий старые имена столбцов с новыми именами столбцов, вы могли бы использовать pd.DataFrame.rename
.
d = {'Jack': 'x098', 'Mahesh': 'y765', 'Xin': 'z432'}
df.rename(columns=d)
x098 y765 z432
0 1 3 5
1 2 4 6
Тем не менее, вы можете легко создать этот словарь и включить его в вызов rename
. Следующее использует тот факт, что при переборе df
мы перебираем каждое имя столбца.
# given just a list of new column names
df.rename(columns=dict(zip(df, new)))
x098 y765 z432
0 1 3 5
1 2 4 6
Это прекрасно работает, если ваши оригинальные имена столбцов являются уникальными. Но если они не, то это ломается.
Настройка 2
неуникальных столбцов
df = pd.DataFrame(
[[1, 3, 5], [2, 4, 6]],
columns=['Mahesh', 'Mahesh', 'Xin']
)
new = ['x098', 'y765', 'z432']
df
Mahesh Mahesh Xin
0 1 3 5
1 2 4 6
Решение 2
pd.concat
с использованием keys
аргумента
Во-первых, обратите внимание, что происходит, когда мы пытаемся использовать решение 1:
df.rename(columns=dict(zip(df, new)))
y765 y765 z432
0 1 3 5
1 2 4 6
Мы не отображали new
список как имена столбцов. Мы закончили тем, что повторили y765
. Вместо этого мы можем использовать keys
аргумент pd.concat
функции во время итерации по столбцам df
.
pd.concat([c for _, c in df.items()], axis=1, keys=new)
x098 y765 z432
0 1 3 5
1 2 4 6
Решение 3
Реконструкция. Это следует использовать, только если у вас есть один dtype
для всех столбцов. В противном случае вы получите dtype
object
все столбцы, и для их преобразования требуется больше словарной работы.
Один dtype
pd.DataFrame(df.values, df.index, new)
x098 y765 z432
0 1 3 5
1 2 4 6
смешанный dtype
pd.DataFrame(df.values, df.index, new).astype(dict(zip(new, df.dtypes)))
x098 y765 z432
0 1 3 5
1 2 4 6
Решение 4
Это трюк с transpose
и set_index
. pd.DataFrame.set_index
позволяет нам установить индекс в строке, но не соответствует set_columns
. Таким образом, мы можем транспонировать set_index
и перенести обратно. Тем не менее, тот же сингл dtype
против смешанногоdtype
здесь применимо предостережение в из решения 3.
Один dtype
df.T.set_index(np.asarray(new)).T
x098 y765 z432
0 1 3 5
1 2 4 6
смешанный dtype
df.T.set_index(np.asarray(new)).T.astype(dict(zip(new, df.dtypes)))
x098 y765 z432
0 1 3 5
1 2 4 6
Решение 5
Используйте a lambda
в pd.DataFrame.rename
этом цикле через каждый элемент new
В этом решении мы передаем лямбду, которая принимает, x
но затем игнорирует ее. Это также занимает, y
но не ожидает этого. Вместо этого итератор задан в качестве значения по умолчанию, и затем я могу использовать его для циклического перехода по одному за раз, независимо от значения x
.
df.rename(columns=lambda x, y=iter(new): next(y))
x098 y765 z432
0 1 3 5
1 2 4 6
И как отметили мне люди в чате sopython , если я добавлю *
промежуточное x
и y
, я смогу защитить свою y
переменную. Хотя в этом контексте я не верю, что это нуждается в защите. Это все еще стоит упомянуть.
df.rename(columns=lambda x, *, y=iter(new): next(y))
x098 y765 z432
0 1 3 5
1 2 4 6