#python #pandas #string #data-cleaning
#питон #панды #строка #очистка данных
Вопрос:
Я работаю над гармонизацией / очисткой довольно «грязного» набора данных в Pandas. Ради демонстрации давайте представим, что это именно этот:
df = pd.DataFrame({"colname": ["ÀÁÂÃÄÅÆ", "Ç", "ÈÉÊË", "ÌÍÎÏ", "Ð", "Ñ", "ÒÓÔÕÖ", "×", "Ø", "ÙÚÛÜ", "Ý", "Þ", "ß"]})
print(df)
colname
0 ÀÁÂÃÄÅÆ
1 Ç
2 ÈÉÊË
3 ÌÍÎÏ
4 Ð
5 Ñ
6 ÒÓÔÕÖ
7 ×
8 Ø
9 ÙÚÛÜ
10 Ý
11 Þ
12 ß
Моя цель — очистить приведенный выше столбец, применив к символам следующее сопоставление:
Before: ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß
After: AAAAAAACEEEEIIIIDNOOOOO OUUUUY S
Хотя цепочка 32 str.replace()
должна выполнить эту работу, мне это не кажется особенно удобочитаемым решением. Например, для первых двух:
df["colname"] = df["colname"].str.replace("À", "A").str.replace("Á", "A")
Вместо этого мне было интересно, можно ли определить следующий словарь сопоставления
sub_dict = {
"À": "A", "Á": "A", "Â": "A", "Ã": "A", "Ä": "A", "Å": "A", "Æ": "A", "Ç": "C",
"È": "E", "É": "E", "Ê": "E", "Ë": "E", "Ì": "I", "Í": "I", "Î": "I", "Ï": "I",
"Ð": "D", "Ñ": "N", "Ò": "O", "Ó": "O", "Ô": "O", "Õ": "O", "Ö": "O", "×": " ",
"Ø": "O", "Ù": "U", "Ú": "U", "Û": "U", "Ü": "U", "Ý": "Y", "Þ": " ", "ß": "S"
}
и применить это сопоставление к столбцу фрейма данных?
Очищенный выходной фрейм данных должен быть следующим:
colname
0 AAAAAAA
1 C
2 EEEE
3 IIII
4 D
5 N
6 OOOOO
7
8 O
9 UUUU
10 Y
11
12 S
Ответ №1:
Да, вы определенно можете это сделать! Имейте в виду, что существуют важные различия между встроенными replace()
и pandas Series.replace(). Последний позволяет передавать словарь и выполнять несколько замен одновременно. В заключение я рекомендую использовать pandas Series.replace()
с вашими словарями:
df["colname"] = df["colname"].replace(sub_dict,regex=True)
Комментарии:
1. Это аккуратно, ха-ха, не знал, что вы можете перейти
regex=True
к.replace
2. Да @Toukenize, и это позволяет передавать гораздо больше объектов (списки, dicts), это намного более гибкий imo.
Ответ №2:
Вы можете преобразовать строку в список символов, разбить список и применить сопоставление sub_dict
к каждому символу, а затем снова сгруппировать символы:
df_out = (
df['colname']
.apply(list)
.explode()
.map(sub_dict)
.groupby(level=0)
.apply(lambda x : ''.join(x))
)
что дает вам желаемый результат:
colname
0 AAAAAAA
1 C
2 EEEE
3 IIII
4 D
5 N
6 OOOOO
7
8 O
9 UUUU
10 Y
11
12 # Check your mapping for "ß", which currently maps to " " instead of "S"