У меня есть набор данных, в котором есть столбцы для количества единиц, проданных за данный месяц - проблема в том, что столбцы ежемесячных единиц названы в формате MM / yyyy, что означает, что у меня есть 12 столбцов информации о единицах на запись.
Так, например, мои данные выглядят так:
ProductID | CustomerID | 04/2018 | 03/2018 | 02/2018 | FileDate |
a1032 | c1576 | 36 | 12 | 19 | 04/20/2018 |
Проблема заключается в том, что каждый месяц появляется новый файл с тем же именем, но с разными заголовками столбцов для информации о единицах за последние 12 месяцев.
Что я хотел бы сделать, так это переименовать столбцы ежемесячных единиц в Месяц1, Месяц2, Месяц3 ... на основе простого регулярного выражения, такого как ([0-9]*)/([0-9]*), которое приведет к выводу:
ProductID | CustomerID | Month1 | Month2 | Month3 | FileDate |
a1032 | c1576 | 36 | 12 | 19 | 04/20/2018 |
Я знаю, что это должно быть возможно с использованием Python, но, поскольку я никогда раньше не использовал Python (я старый разработчик .Net), я, честно говоря, понятия не имею, как этого добиться.
Я провел небольшое исследование переименования столбцов в Python, но ни один из них не упомянул сопоставление шаблонов для переименования столбца, например:
df = df.rename(columns = {'oldName1': 'newName1', 'oldName2': 'newName2'})
ОБНОВЛЕНИЕ: данные, которые я показываю в моем примере, - это только подмножество столбцов; Всего в моем наборе данных 120 столбцов, только 12 из которых нужно переименовать, поэтому я подумал, что регулярное выражение может быть самым простым способом.






Если у вас есть несколько наборов имен, в которые вы хотите преобразовать, то вместо использования переименования может быть проще просто передать новый список в атрибут df.columns
df.columns = ['ProductID','CustomerID']+['Month{}'.format(i) for i in range(12)]+['FileDate']
Если вы хотите использовать переименование, если вы можете написать функцию find_new_name, которая выполняет необходимое преобразование для одного имени, вы можете переименовать весь список old_names с помощью
df.rename(columns = {oldname:find_new_name(old_name) for old_name in old_names})
Или, если у вас есть функция, которая принимает новое имя и выясняет, какое старое имя ему соответствует, тогда это будет
df.rename(columns = {find_old_name(new_name):new_name for new_name in new_names})
Вы также можете сделать
for new_name in new_names:
old_name = find_new_name(old_name)
df[new_name] = df[old_name]
При этом данные будут скопированы в новые столбцы с новыми именами, а не переименованы, так что затем вы можете выбрать только те столбцы, которые вам нужны.
import re
# regex pattern
pattern = re.compile("([0-9]*)/([0-9]*)")
# get headers as list
headers = list(df)
# apply regex
months = 1
for index, header in enumerate(headers):
if pattern.match(header):
headers[index] = 'Month{}'.format(months)
months += 1
# set new list as column headers
df.columns = headers
Поскольку rename может принимать функцию в качестве преобразователя, мы могли бы определить настраиваемую функцию, которая возвращает новое имя столбца в новом формате, если старое имя столбца совпадает с регулярным выражением; в противном случае возвращает то же имя столбца. Например,
import re
def mapper(old_name):
match = re.match(r'([0-9]*)/([0-9]*)', old_name)
if match:
return 'Month{}'.format(int(match.group(1)))
return old_name
df = df.rename(columns=mapper)
Спасибо за ответ - одна из причин, по которой я рассматривал Regex, заключается в том, что мой полный набор данных содержит 120 столбцов. Я понял, что не включил эту информацию в свой вопрос, и соответствующим образом обновил ее.