在設計「雄:Python : 匯出 PDF 表格為試算表資料」中的轉換工具,由 PDF 擷取而來的資料被轉為pandas 的 DataFrame,最後使用 DataFrame 的 to_excel 輸出為 Excel 格式的檔案。不過如果照預設值,輸出的資料在Excel中,都是「文字」的格式;此外同事提供的原始資料,除了流水號的欄位,其它欄位的數字都有加上逗號(例: 12,345、7,890),所以在將「文字格式」的數字轉為數字型態時,得多考慮這一點。
在 Python 中,將文字型態的數字,轉為數字型態的方法有很多,不過,試了一下,如果想將「12,345」轉為「12345」,使用 locale 的 atof 或是 atoi 應該是較簡潔,例如:
import locale
from locale import atof
locale.setlocale(locale.LC_NUMERIC, '')
atof('12,345')
但是如果遇到不是數字的內容,或是空字串,例如:
atof('這不是數字')
atof('')
就會出現類似這樣的錯誤訊息:
ValueError: could not convert string to float: ''
所以在轉換的時候,還需要檢查一下是否為數字的。
判斷是否為數字,可以使用 Python 的 isnumeric() ,不過,像以下的格式:
- 12,345
- -12345
- 12.345
因為帶有逗號、減號或小數點,isnumeric() 都會傳回 False,所以我先利用 re.sub ,將非數字的符號先拿掉後,再用 isnumeric() 來判斷。
綜合前面的條件,利用底下的 convert_number_strings_to_numbers ,就可以用來將 df (pandas 的 DataFrame) ,指定的欄位 columns (欄位順號 list),轉為 float 數字:
def convert_number_strings_to_numbers(df, columns):
locale.setlocale(locale.LC_NUMERIC, '')
for i in columns:
df[i] = df[i].apply(lambda x: x if x=='' or not re.sub(r'[,.-]', '', x).isnumeric() else atof(x))
return df
沒有留言:
張貼留言