[英]Using case_when with mutate equivalent in python
我剛剛開始使用 python,我正在嘗試將我創建的一些 R 函數遷移到 python。 我對如何基於正則表達式條件創建變異列感到困惑。
目標
我有一個包含文本的 dataframe。 我想提取文本中提到分數的部分,該分數包含字母 m 后跟數字,例如“m3”或“M5”等。想法是,如果存在正則表達式,則應提取數字到名為 MStage 的列。
由於各種邊緣情況,正則表達式有點復雜,因此必須使用 ifelse(或 case_when)類型子句按順序執行多個正則表達式。
R 代碼如下所示:
dataframe <- dataframe %>%
mutate(
MStage = map(
mytext, ~ case_when(
grepl("(?<=\\d)\\s*[Mm](?:\\s|=)*\\d+", .x,perl = TRUE) ~ stringr::str_replace(stringr::str_extract(.x, "(?<=\\d)\\s*[Mm](?:\\s|=)*\\d+"), "M", ""),
grepl("(?=[^\\.]*[Bb]arr)[^\\.]*\\s+\\d{2}\\s*[cm]*\\s*(to |-| and)\\s*\\d{2}\\s*[cm]*\\s*", .x, ignore.case = TRUE, perl = TRUE) ~ as.character(as.numeric(sapply(stringr::str_extract_all(stringr::str_extract(.x, "\\d{2}\\s*[cm]*\\s*(to|-|and)\\s*\\d{2}\\s*[cm]*\\s*"), "\\d{2}"), function(y) abs(diff(as.numeric(y)))))),
grepl("(?=[^\\.]*cm)(?=[^\\.]*[Bb]arr)(?=[^\\.]*(of |length))[^\\.]*", .x, perl = TRUE) ~ stringr::str_extract(paste0(stringr::str_match(.x, "(?=[^\\.]*cm)(?=[^\\.]*[Bb]arr)(?=[^\\.]*(of |length))[^\\.]*"), collapse = ""), "\\d+"),
grepl("(\\.|^|\n)(?=[^\\.]*(small|tiny|tongue|finger))(?=[^\\.]*[Bb]arr)[^\\.]*(\\.|\n|$)", .x, perl = TRUE) ~ stringr::str_replace(.x, ".*", "1"),
TRUE ~ "Insufficient"
)
)
)
我的嘗試
我已經開始嘗試使用以下代碼將其轉換為 python:
df = df.assign(col = ['pos' if df['text'].str.contains('(?<=\\d)\\s*[Mm](?:\\s|=)*\\d+') else 'Insuf' ])
雖然我得到的錯誤是:
問題
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
如果正則表達式為真,我希望能夠添加提取數字的功能(以及根據 R 代碼的其他正則表達式
你得到這個錯誤的原因是因為if
這里期待一個 boolean,但你給它提供了一系列布爾值。 通常,您可以使用 lambda function 來解決此問題。
import re
pat = '(?<=\\d)\\s*[Mm](?:\\s|=)*\\d+'
df = df.assign(col = lambda x: 'pos' if re.search(pat, x) else 'Insuf')
要提取數字,只需使用不同的re
方法(如果您只需要第一次出現,可能是re.match()
)代替'pos'
,或者用re.match()
和fillna()
替換if else
'Insuf'
在assign()
的另一邊。
df = df.assign(col = lambda x: re.match(pat, x)).fillna(value='Insuf')
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.