Я сосредоточусь на двух вещах:
'$'
или отбрасывать первый символ каждого заголовка столбца. ОП уже сделал этот шаг. Вместо этого я хочу сосредоточиться на замене существующего объекта columns
на новый, заданный список заменяющих имен столбцов. df.columns = new
где new
- список имен новых столбцов, так же просто, как и он получает. Недостатком этого подхода является то, что он требует редактирования существующего атрибута columns
существующего dataframe, и он не выполняется inline. Я покажу несколько способов выполнить это с помощью конвейерной обработки без редактирования существующего фрейма данных. Настройка 1 Чтобы сосредоточиться на необходимости переименовать имена заменяемых столбцов на уже существующие list, я создам новый образец dataframe 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
Mixed 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 Используйте 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
Проблема в том, что вы смешиваете JOINs. У вас есть как неявные, так и явные объединения. Явный синтаксис JOIN с предложением ON имеет более высокий приоритет над неявным соединением с запятыми. В результате псевдоним для таблиц plant
и offerte
не будет доступен в предложении ON. Попробуйте использовать один и тот же тип JOIN:
SELECT p.plantnaam, o.levcode, o.offerteprijs
FROM
(
SELECT plantcode , MIN(offerteprijs) AS offprijs
FROM offerte
GROUP BY plantcode
) s
INNER JOIN plant p
ON s.plantcode = p.plantcode
INNER JOIN offerte o
ON s.offprijs = o.offerteprijs
ORDER BY p.plantnaam, l.levcode