2017-03-07 66 views
1

我有一個大數據框與人的數據。我想扁平所有奇怪的變音符號並將它們轉換爲最接近的ASCII字符。基於一個解決方案,我發現在我的SO做到以下幾點:正常化錯過波蘭字符

for column in df.columns: 
      df[column] = df[column].astype("str").str.normalize('NFKD').str.encode('ascii', errors='ignore').str.decode('utf-8') 

它適用於大多數情況下(沒有檢查了所有的),但是我已經注意到它忽略字母「L」在波蘭。例如Lech Wałęsa被翻譯爲Lech Waesa,而我的期望是看Lech Walesa。我的猜測是,這是ignore參數在str.encode方法中的作用。任何想法如何使它適用於任何變音符號?

回答

1

嘗試使用unidecode,對於您描述的示例完美工作。

from unidecode import unidecode 

for column in df.columns: 
    df[column] = [unidecode(x) for x in df[column].values] 
+0

這對我來說非常合適。我選擇它作爲最好的答案,因爲它很簡單。 – pawelty

1

看什麼normalize('NFKD')實際上不會給你的輸入字符串"Lech Wałęsa"

import unicodedata 
s = "Lech Wałęsa" 
print(list(unicodedata.normalize("NFKD", s))) 

['L', 'e', 'c', 'h', ' ', 'W', 'a', 'ł', 'e', '̨', 's', 'a'] 

正如你所看到的,字符「E」被分解成字母「e」和音調符號的「̨」 ,但'ł'不會發生這種分解。看來unicode字符拉丁小寫字母L與STROKE'ł'和拉丁大寫字母L與STROKE'英文'是among the few characters unicode分解不起作用。

現在,當您使用normalize("NFKD")的輸出作爲encode("ascii", errors="ignore")的輸入時,會發生什麼情況是,無法以ASCII字符表示的所有字符都會被忽略,從而使輸出爲"Lech Waesa"

你可以做的解決這個問題的方法是在你從支持分解的字符中刪除變音符號之前,用'L'和'l'手動替換例外的'Ł'和'ł'。你必須像這樣改變你的代碼:

for column in df.columns: 
    df[column] = (df[column].astype("str") 
          .str.replace("ł", "l") 
          .str.replace("Ł", "L") 
          .str.normalize('NFKD') 
          .str.encode('ascii', errors='ignore') 
          .str.decode('utf-8')) 
+0

感謝您的解釋!我沒有意識到unicode分解對某些字符不起作用的事實。在我的數據中,我可以期待所有這些字符,所以我需要爲它們中的每一個添加單獨的替換函數。 – pawelty