#python #pyspark #apache-spark-sql #pyspark-dataframes
#python #pyspark #apache-spark-sql #pyspark-фреймы данных
Вопрос:
у меня есть следующий столбец в фрейме данных, который содержит числа, состоящие из 6 цифр и кратные шести, чего я пытаюсь добиться, так это разбиения столбца на группы по 2 подгруппы по 3 цифры, поскольку существует взаимосвязь. Это фрейм данных,
------------------------ ---
|Col1 |len|
------------------------ ---
|001200 |6 |
|201400 |6 |
|401800 |6 |
|201400401800 |12 |
|001200201400401800 |18 |
|001200201400401800801999|24 |
------------------------ ---
Чего я ожидаю, так это
------------------------ ------------------------------- ---
|Col1 |processed_column |len|
------------------------ ------------------------------- ---
|001200 |001-200 |6 |
|201400 |201-400 |6 |
|401800 |401-800 |6 |
|201400401800 |201-400,401-800 |12 |
|001200201400401800 |001-200,201-400,401-800 |18 |
|001200201400401800801999|001-200,201-400,401-800,801-999|24 |
------------------------ ------------------------------- ---
Одно из решений, которое я могу придумать, — это проверить len и разделить его на основе этого, но тогда я должен продолжать писать условие F.when для каждой длины и разделять его соответствующим образом.
df = df.withColumn(
"processed_column",
F.when(
F.col("len") == 6,
F.concat(
F.substring(F.col("Col1"), 0, 3),
F.lit("-"),
F.substring(F.col("Col1"), 3, 3),
),
)
.when(
F.col("len") == 12,
F.concat(
F.substring(F.col("Col1"), 0, 3),
F.lit("-"),
F.substring(F.col("Col1"), 4, 3),
F.lit(","),
F.substring(F.col("Col1"), 7, 3),
F.lit("-"),
F.substring(F.col("Col1"), 10, 3),
),
)
.otherwise(F.col("Col1")),
)
есть ли лучший способ, который может обрабатывать это динамически?
Комментарии:
1. используйте regexp_replace, а затем обрежьте лишнюю конечную запятую:
df.withColumn('processed_column', F.expr(r"rtrim(',',regexp_replace(Col1, '(\d{3})(\d{3})', '$1-$2,'))"))
2. позвольте мне проверить это и дать вам обратную связь.
3. @jxc это работает, буду признателен, если вы сможете объяснить синтаксис регулярных выражений
Ответ №1:
Я не знаю pyspark, но string в Python, вы можете сделать это, чтобы изменить все строки, кратные шести, на стиль, который вы задали в вопросе.
def f(s):
return ','.join([s[i*6:i*6 3] '-' s[i*6 3:i*6 6] for i in range(len(s)//6)])
print(f('401800'))
print(f('201400401800'))
print(f('001200201400401800'))
print(f('001200201400401800801999'))
401-800
201-400,401-800
001-200,201-400,401-800
001-200,201-400,401-800,801-999
Комментарии:
1. спасибо вам за это @watfe, я смог создать функцию udf, используя ее 🙂
Ответ №2:
def myFunction(s):
return ','.join([s[i*6:i*6 3] '-' s[i*6 3:i*6 6] for i in range(len(s)//6)])
udf_myFunction = F.udf(myFunction)
df.withColumn('new_string', udf_myFunction("Col1")).show()