Замените подстроку в строке, используя список или dict в PolarsPython

Программы на Python
Ответить
Anonymous
 Замените подстроку в строке, используя список или dict в Polars

Сообщение Anonymous »

В данный момент я работаю над моделью НЛП и оптимизирую этапы предварительной обработки.
Поскольку я использую пользовательскую функцию, поляры не могут распараллелить операцию.
Я пробовал несколько вещей с полярами «replace_all» и некоторыми «.when.then.otherwise», но пока не нашел решения.
В этом случае я выполняю «расширяющиеся сокращения» (например, Я -> Я).
Сейчас я использую это:

Код: Выделить всё

import re
import polars as pl

# This is only a few example contractions that I use.
cList = {
"i'm": "i am",
"i've": "i have",
"isn't": "is not"
}

c_re = re.compile("(%s)" % "|".join(cList.keys()))

def expandContractions(text, c_re=c_re):
def replace(match):
return cList[match.group(0)]

return c_re.sub(replace, text)

df = pl.DataFrame({"Text": ["i'm i've, isn't"]})
df["Text"].map_elements(expandContractions)
Выходы

Код: Выделить всё

shape: (1, 1)
┌─────────────────────┐
│ Text                │
│ ---                 │
│ str                 │
╞═════════════════════╡
│ i am i have, is not │
└─────────────────────┘
Но хотелось бы использовать все преимущества производительности поляров, поскольку наборы данных, которые я обрабатываю, довольно велики.

Тест производительности:

Код: Выделить всё

#This dict have 100+ key/value pairs in my test case
cList = {
"i'm": "i am",
"i've": "i have",
"isn't": "is not"
}

def base_case(sr: pl.Series) -> pl.Series:
c_re = re.compile("(%s)" % "|".join(cList.keys()))
def expandContractions(text, c_re=c_re):
def replace(match):
return cList[match.group(0)]

return c_re.sub(replace, text)

sr = sr.map_elements(expandContractions)
return sr

def loop_case(sr: pl.Series) -> pl.Series:

for old, new in cList.items():
sr = sr.str.replace_all(old, new, literal=True)

return sr

def iter_case(sr: pl.Series) -> pl.Series:
sr = functools.reduce(
lambda res, x: getattr(getattr(res, "str"), "replace_all")(
x[0], x[1], literal=True
),
cList.items(),
sr,
)
return sr
Все они возвращают одинаковые результаты, и вот среднее время для 15 циклов по ~10 000 выборок с длиной выборки ~500 символов.

Код: Выделить всё

Base case: 16.112362766265868
Loop case: 7.028670716285705
Iter case: 7.112465214729309
Таким образом, при использовании любого из этих методов скорость увеличивается более чем в два раза, и это в основном благодаря API-вызову Polars "replace_all".
В итоге я использовал циклический случай, с тех пор у меня на один модуль меньше для импорта.
См. ответ на этот вопрос jqurious

Подробнее здесь: https://stackoverflow.com/questions/752 ... -in-polars
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»