Строковые манипуляции в python udf для pyspark - PullRequest
1 голос
/ 19 июня 2020

Я пытаюсь закодировать пример использования ниже, но застрял в том, как манипулировать определенным требованием в python

требование - это когда мы получаем строку, если у нее есть AM или PM, мы должны извлеките целые числа, такие как 1130AM, мой результат должен быть 1130. если содержит U между целыми числами, например, 1130U230AM, мне нужно извлечь значения numeri c до и после U и умножить их. Я закодировал 1-й вариант использования извлечения чисел, но при умножении, когда в середине стоит буква «U», я не уверен, как это кодировать. Пожалуйста, помогите.

def test_func(val):
    val = str(val)
    x = re.compile("[A-Za-z]+".replace('.', '\.'), re.IGNORECASE)
    y = re.compile("[0-9,.]+".replace('.', '\.'), re.IGNORECASE)
    x_1 = re.search(x, val)
    y_1 = re.search(y, val)
try:
    if not re.search('[AM|PM]$', val):
        return ''

Ответы [ 2 ]

4 голосов
/ 19 июня 2020

Вам не нужно использовать udf для этого случая в Spark, поскольку udf медленные .

Вместо этого используйте встроенные функции Spark when+otherwise и regexp_extract,regexp_repla ce функции.

Example:

#sample dataset
df=spark.createDataFrame([('1130AM',),('1130PM',),('1130U230AM',),('1130UAM',)],['tim_val'])

#using rlike we are matching if string has u or am/pm then caluculating new_col value    
df.withColumn("new_col",when(lower(col("tim_val")).rlike("(u)(.\\d+)"),\
    (regexp_extract(col("tim_val"),"(.*)(?i)(u)(.\\d+)",1)) * (regexp_extract(col("tim_val"),"(.*)(?i)(u)(.\\d+)",3))).\
when(lower(col("tim_val")).rlike("(?i)(u|am|pm)"),regexp_replace(col('tim_val'),'(?i)(u|am|pm)','')).\
otherwise('No')).\
show()

#+----------+--------+
#|   tim_val| new_col|
#+----------+--------+
#|    1130AM|    1130|
#|    1130PM|    1130|
#|1130U230AM|259900.0|
#|   1130UAM|    1130|
#+----------+--------+
0 голосов
/ 19 июня 2020

Я написал это без использования регулярных выражений, так как по моему опыту их иногда бывает очень трудно понять.

def extract_value(val):
    val = val[:-2]                        # remove AM or PM from end of val

    if 'U' in val:
        val = val.split('U')              # split into the two numbers
        val = int(val[0]) * int(val[1])   # multiply integer values
    else:
        val = int(val)                    # convert string to integer

    return val


value_to_extract = '1130U230AM'

output = extract_value(value_to_extract)

Значение, сохраненное в output, в этом случае будет 259900, что является ответом на 1130 * 230. Это простой скрипт, который определенно может быть улучшен при необходимости.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...