【Python自動化Excel】Python與pandas字串操作
Python之所以能夠成為流行的資料分析語言,有一部分原因在於其簡潔易用的字串處理能力。
Python的字串物件封裝了很多開箱即用的內建方法,處理單個字串時十分方便;對於Excel、csv等表格檔案中整列的批量字串操作,pandas庫也提供了簡潔高效的處理函式,幾乎與內建字串函式一一對應。也就是說:
-
單個字串處理,用Python內建的字串方法;
-
表格整列的字串處理,用pandas庫中的字串函式;
本文就以常用的資料處理需求,來對比使用以上兩種方式的異同,從而加深對Python
和pandas
字串操作的理解。(本文所有資料都是為了演示用的假資料,切勿當真!)
)
一、替換(去除空格)
場景:在問卷收集的姓名欄位中,不少填寫者會誤輸入空格,造成資料匹配不一致的問題。
Python
names = '劉 備、關 羽、 張 飛、趙 雲、馬 超、黃 忠'
names = names.replace(' ','')
print(names)
output
劉備、關羽、張飛、趙雲、馬超、黃忠
pandas
df['姓名'] = df['姓名'].str.replace(' ','')
output
二、分列
場景:在問卷收集資料的時候,多選題的資料往往是帶有分隔符的。在分類彙總前往往需要按分隔符進行分列。
Python
hobbyStr = "足球┋排球┋羽毛球┋籃球" hobbyList = hobbyStr.split('┋')
output
['足球', '排球', '羽毛球', '籃球']
pandas
# 利用split進行分列,expand = True 返回dataframe;expand=False返回Series
hobbyDf = df['愛好'].str.split('|', expand=True)
# 將hobbyDf 與 df安裝索引合併
df2 = pd.merge(df, hobbyDf, how="left", left_index=True, right_index=True)
三、切片:擷取資料
字串是由一個個字元組成的序列,在Python中可以直接對字串進行切片操作,來進行擷取資料。
如“XX市四季家園二區22幢203室”,可以看作是下圖中16個字元值組成的序列。而切片的語法是:
Python
addressStr = "XX市四季家園二區22幢203室"
print(f"城市:{addressStr[:3]}")
print(f"小區:{addressStr[3:9]}")
output
城市:XX市
小區:四季家園二區
pandas
-
提取城市名稱,由於城市名稱的字數相同,可以直接切片擷取前三個。
df["城市"] = df["地址"].str[:3]
-
提取小區名,稍有點複雜。因為小區名稱長度是不一樣長的。可以利用字串處理的天花板: 正則表示式
。詳細處理方法,見下文五、正則表示式
示例1。
四、補齊資料
有時候,我們在電腦中按檔名排序的時候,你可能會遇到下面的情況:
在不同系統中,我們希望是按數值排序,但偏偏系統卻是按字元排序的,如某些車載播放器中。比較好的解決方法就是在前面新增0,補齊資料位數。資料量大的時候,手動修改很麻煩,Python字串處理的zfill()
函式就可以解決這個問題。
Python
myStr = "1章節"
print(myStr.zfill(4)) # 整個字串補齊到4位
output
01章節
pandas
df["新檔名"] = "第"+df["檔名"].str[1:].str.zfill(8)
配合os.rename()
便可以批量重新命名。關鍵程式碼如下
df.apply(lambda x: os.rename( path + x["檔名"], path + x["新檔名"]), axis=1)
五、正則表示式
遇到複雜的字串處理需求時,Python有優勢就可以體現出來了。因為python和pandas有一個超強的字串處理武器:正則表示式。正則表示式可以匹配字串的格式特點,如電子郵箱的地址格式、網址的地址格式、電話號碼格式等。如何寫好正則表示式,這是一門精深的學問,本文介紹幾個正則表示式的常用案例,淺嘗輒止。
注:Python預設不支援正則表示式語法,而pandas直接支援正則表示式語法,這裡重點介紹pandas處理表格資料。
1.提取長度不一樣的小區名
思路:
-
提取上面小區名,可以歸納一下地址中小區名的格式特點:
蘇州市之後,幢號數字之前的中文字元
。 -
Series
的str.extract()
,可用正則從字元資料中抽取匹配的資料;
## 匹配中文字元的正則表示式: [\u4e00-\u9fa5]
pattern = r'蘇州市([\u4e00-\u9fa5]+)[0-9]+幢'
df["小區"] = df["地址"].str.extract(pattern, expand=False)
2.提取幾幢幾室
思路:幾幢幾室,格式都是數字+幢
和數字+室
-
數字可以用 [0-9]
或\d
來匹配; -
+
表示1個或多個。
pattern = r'([0-9]+)幢'
df["幢號"] = df["地址"].str.extract(pattern, expand=False)
pattern = r'(\d+)室'
df["室號"] = df["地址"].str.extract(pattern, expand=False)
六、apply函式
apply 函式:可以對DateFrame
進行逐行或逐列進行處理。
1.增加一列,將幢號按照奇偶數分類
將幢號為奇數的為A區,偶數的為B區
# 定義處理的函式,共apply函式呼叫,傳入的引數為一個Series物件
def my_func(series):
if (series["幢號"]) % 2 != 0:
return "A區"
else:
return "B區"
df["幢號分類"] = df.apply(my_func, axis=1)
上述程式碼中apply函式,有兩個引數
-
第一個引數:處理邏輯的函式名。主要傳入名稱,這裡為 my_func
; -
第二個引數: axis = 1
,表示按列處理。即傳入的是每一行的Series
。
output
2.增加一列,字典對映
def my_func2(series):
# 對映字典,key為小區名,value為小區稱號
my_dict = {
'吉祥如意家園': '最佳好運小區',
'科技村': '最佳科創小區',
'四季家園': '最佳風光小區',
'永珍更新家園': '最佳風采小區',
}
# 每一行小區名稱,切片擷取至倒數第2個,即-2
nameKey = series['小區'][:-2]
return my_dict[nameKey]
df["小區稱號"] = df.apply(my_func2, axis=1)
output
結語
本文演示的字串操作:替換
、分列
、切片擷取
、補齊資料
、正則表示式
、apply()函式
常見於資料分析的資料清洗環節,替換
、分列
、切片擷取
在Excel中也很容易實現,正則表示式
可以說是Python處理複雜字串問題的一大利器,apply()函式
可以實現自定義函式
處理表格型的資料,十分靈活、威力巨大。由於篇幅有限,正則表示式
、apply()函式
本文就點到為止,今後值得整理更多相關案例。