Я не могу уложить в голове это. Допустим, у меня есть словарь регулярных выражений и строк замены, которые я хочу заменить, и если ни одно из этих регулярных выражений не совпадает (когда возвращается False), я хочу возобновить работу со следующим оператором if.
Итак, вместо этого не проверяются данные в «новых данных»...
all_items = pl.DataFrame(
{
"data": ["Swedish fish", "English tea", "", "", ""],
"ISO_codes": ["fin", "nor", "eng", "eng", "swe"],
})
replacement_rules = {
r"^Swe.*": "Svenska",
r"^Eng.*": "English",
}
iso_tranlation = {
"swe": "Svenska",
"eng": "English",
"nor": "Norsk",
"fin": "Finska på finska",
}
for pattern, replacement in replacement_rules.items():
all_items = (
all_items.lazy()
.with_columns(
pl.when(pl.col("data").str.contains(pattern))
.then(pl.lit(replacement))
.alias("new_data")
)
.collect()
)
all_items = (
all_items.lazy()
.with_columns(
pl.when(pl.col("ISO_codes").str.len_chars() > 0)
.then(
pl.col("ISO_codes")
.replace(iso_tranlation , default = "Unknown ISO Code")
)
.alias("new_data")
)
.collect()
)
...я хотел бы сделать что-то вроде этого:
expressions = [
pl.when(pl.col("data").str.contains(pattern))
.then(pl.lit(replacement))
for pattern, replacement in replacement_rules.items()]
all_items = (
all_items.lazy()
.with_columns(
expressions.explode_and_pipe()
.when(pl.col("ISO_codes").str.len_chars() > 0)
.then(
pl.col("ISO_codes")
.replace(iso_tranlation , default = "Unknown ISO Code")
)
.alias("new_data")
)
.collect()
)
Есть ли способ добиться этого expressions.explode_and_pipe()
?
Обновлено: Это полученный фрейм данных, который мне нужен:
shape: (5, 3)
┌──────────────┬───────────┬──────────┐
│ data ┆ ISO_codes ┆ new_data │
│ --- ┆ --- ┆ --- │
│ str ┆ str ┆ str │
╞══════════════╪═══════════╪══════════╡
│ Swedish fish ┆ fin ┆ Svenska │
│ English tea ┆ nor ┆ English │
│ ┆ eng ┆ English │
│ ┆ eng ┆ English │
│ ┆ swe ┆ Svenska │
└──────────────┴───────────┴──────────┘
Итак, цель состоит в том, чтобы закоротить и сделать так, чтобы каждый элемент new_data
был либо первым соответствием replacement_rules
для data
, либо, если совпадений не найдено, первым соответствием iso_tranlation
[так в оригинале] для ISO_code
?
Может быть, вы ищете что-то подобное? (coalesce
может быть той функцией, которая вам нужна.)
replacements = pl.lit(None)
for pattern, replacement in replacement_rules.items():
replacements = (
pl.when(pl.col("data").str.contains(pattern))
.then(pl.lit(replacement))
.otherwise(replacements)
)
iso_translations = pl.col("ISO_codes").replace(
iso_translation, default = "Unknown ISO Code"
)
all_items.with_columns(new_data=pl.coalesce(replacements, iso_translations))
shape: (5, 3)
┌──────────────┬───────────┬──────────┐
│ data ┆ ISO_codes ┆ new_data │
│ --- ┆ --- ┆ --- │
│ str ┆ str ┆ str │
╞══════════════╪═══════════╪══════════╡
│ Swedish fish ┆ fin ┆ Svenska │
│ English tea ┆ nor ┆ English │
│ ┆ eng ┆ English │
│ ┆ eng ┆ English │
│ ┆ swe ┆ Svenska │
└──────────────┴───────────┴──────────┘
Ух ты, читая о слиянии, кажется, что этот подход должен сработать. Завтра попробую первым делом!
Я позаимствовал вашу таблицу конечных результатов.
выражения «когда/то» также можно объединять в цепочки:
pl.when().then().when().then()
Это даст вам семантику if/elif:
IF ...
ELIF ...
ELIF ...
False/None можно использовать в качестве начального «недействующего параметра» для программного создания:
expr = pl.when(False).then(None)
for pattern, replacement in replacement_rules.items():
expr = expr.when(pl.col("data").str.contains(pattern))
expr = expr.then(pl.lit(replacement))
expr = expr.when(pl.col("ISO_codes").str.len_chars() > 0)
expr = expr.then(
pl.col("ISO_codes")
.replace(iso_translation, default = "Unknown ISO Code")
)
>>> df.with_columns(new_data = expr)
shape: (5, 3)
┌──────────────┬───────────┬──────────┐
│ data ┆ ISO_codes ┆ new_data │
│ --- ┆ --- ┆ --- │
│ str ┆ str ┆ str │
╞══════════════╪═══════════╪══════════╡
│ Swedish fish ┆ fin ┆ Svenska │
│ English tea ┆ nor ┆ English │
│ ┆ eng ┆ English │
│ ┆ eng ┆ English │
│ ┆ swe ┆ Svenska │
└──────────────┴───────────┴──────────┘
Очень хорошо! Именно этого пути я и добивался изначально. Эти два ответа должны оказаться очень полезными для людей в будущем.
Вы хотите сказать, что
all_data
— это неправильный вывод? то есть вместо этого первая строка должна бытьSvenska
? Если да, можете ли вы добавить ожидаемый результат?