我有一個包含字串的資料框(~100k 行),我需要從中提取多個專案并為其創建新列。
樣本資料
import pandas as pd
import re
s = pd.Series(['param1=1¶m2=¶m3=ena¶m4=n2oi3-284&',
'param1=2¶m2=2iot¶m3=¶m4=&',
'param1=3¶m2=afv¶m3=39¶m4=4obgg942n&',
'param1=4¶m2=¶m3=1291¶m4=0g2n48a&'])
我可以將正則運算式re.compile(r"=(.*?)&)"與 一起使用str.extractall,然后解開生成的資料框,選擇并附加我想要的列。
| 比賽 | 0 | 1 | 2 | 3 |
|---|---|---|---|---|
| 0 | 1 | NaN | 埃娜 | n2oi3-284 |
| 1 | 2 | 2iot | NaN | NaN |
| 2 | 3 | 自動對焦 | 39 | 4obgg942n |
| 3 | 4 | NaN | 1291 | 0g2n48a |
但是當我測驗它時,它比在字典中為每個引數創建唯一的正則運算式要慢,例如r"1=(.*?)&",然后遍歷該字典并為每個正則運算式使用列分配。
params = {'param1': re.compile(r"1=(.*?)&"),
'param2': re.compile(r"2=(.*?)&"),
'param3': re.compile(r"3=(.*?)&"),
'param4': re.compile(r"4=(.*?)&")}
for k, rx in params.items():
df[k] = s.str.extract(rx, expand=False)
當我使用 %%timeit 時,似乎回圈遍歷正則運算式字典并為每個創建一個新列比使用str.extractall(忽略任何型別的列分配/結果資料框操作)更快。
rx = re.compile(r"=(.*?)&")
%%timeit -n 100
s.str.extractall(rx)
每個回圈 2.56 ms ± 407 μs(7 次運行的平均值 ± 標準偏差,每次 100 次回圈)
%%timeit -n 100
for rx in params.values():
s.str.extract(rx, expand=False)
每個回圈 791 μs ± 152 μs(7 次運行的平均值 ± 標準偏差,每次 100 次回圈)
為什么是這樣?我是否錯誤地計時功能/比較不同的東西?一次遍歷該列不應該比遍歷該列 4 次更快嗎?
str.extract和str.extractall 的檔案對此沒有任何說明。查看extractall與extract的源代碼,我無法確定為什么一個比另一個更快。
謝謝!
uj5u.com熱心網友回復:
根據源代碼extractall使用串列并附加到這些串列中,如果經常使用可能會很慢。
extractall嘗試保持動態,因為它將捕獲所有可能的匹配項,因此也會遍歷整個字串,extract將在第一個匹配項時回傳。如果你只關心第一場比賽,你也extract可以像這樣使用:
s.str.extract(re.compile(r"param1=(.*?)&*param2=(.*?)&*param3=(.*?)&*param4=(.*?)&"))
那么也許extract更適合您的用例呢?
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/377509.html
上一篇:兩個字串之間的正則運算式
