如何在pyspark中动态拆分和分组数字
how to split and group numbers dynamically in pyspark
我在数据框中有以下列,它的数字是 6 位数字和 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")),
)
是否有更好的方法可以动态处理此问题?
我不知道 pyspark,但是 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
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()
我在数据框中有以下列,它的数字是 6 位数字和 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")),
)
是否有更好的方法可以动态处理此问题?
我不知道 pyspark,但是 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
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()