从现有数据框中列的子字符串创建新的 Pyspark 数据框
Creating new Pyspark dataframe from substrings of column in existing dataframe
我有一个如下所示的 Pyspark 数据框,需要创建一个新的数据框,其中只有一列由原始数据框中的所有 7 位数字组成。这些值都是字符串。 Column1 应该被忽略。忽略 Column2 中的非数字和单个 7 位数字非常简单,但是对于具有两个单独的 7 位数字的值,我很难将它们单独提取出来。这需要自动化并能够 运行 在其他类似的数据帧上。这些数字始终为 7 位数字,并且始终以“1”开头。有什么建议吗?
+-----------+--------------------+
| COLUMN1| COLUMN2|
+-----------+--------------------+
| Value1| Something|
| Value2| 1057873 1057887|
| Value3| Something Something|
| Value4| null|
| Value5| 1312039|
| Value6| 1463451 1463485|
| Value7| Not In Database|
| Value8| 1617275 1617288|
+-----------+--------------------+
生成的数据框应如下所示:
+-------+
|Column1|
+-------+
|1057873|
|1057887|
|1312039|
|1463451|
|1463485|
|1617275|
|1617288|
+-------+
- 更新:
反应很好,但不幸的是我使用的是不同意的旧版本 Spark。我用下面的方法解决了这个问题,虽然它有点笨拙......它有效。
from pyspark.sql import functions as F
new_df = df.select(df.COLUMN2)
new_df = new_df.withColumn('splits', F.split(new_df.COLUMN2, ' '))
new_df = new_df.select(F.explode(new_df.splits).alias('column1'))
new_df = new_df.filter(new_df.column1.rlike('\d{7}'))
IIUC,您可以使用正则表达式和 str.extractall
:
df2 = (df['COLUMN2'].str.extractall(r'(\b\d{7}\b)')[0]
.reset_index(drop=True).to_frame(name='COLUMN1')
)
输出:
COLUMN1
0 1057873
1 1057887
2 1312039
3 1463451
4 1463485
5 1617275
6 1617288
正则表达式:
( start capturing
\b word boundary
\d{7} 7 digits # or 1\d{6} for "1" + 6 digits
\b word boundary
) end capture
这是一种用于 spark 2.4+ 的高阶 lambda 函数的方法,其中我们按 space 拆分列,然后过滤以 0-9 开头且长度为 n (7) 的词,然后展开:
n = 7
df.selectExpr(f"""explode(filter(split(COLUMN2,' '),x->
x rlike '^[0-9]+' and length(x)={n})) as COLUMN1""").show(truncate=False)
+-------+
|COLUMN1|
+-------+
|1057873|
|1057887|
|1312039|
|1463451|
|1463485|
|1617275|
|1617288|
+-------+
我喜欢@nky 并投了票。替代方案也可以使用 pysparks 存在于 3.0+
的高阶函数中
new = df.selectExpr("explode(split(COLUMN2,' ')) as COLUMN1").where(F.expr("exists(array(COLUMN1), element -> element rlike '([0-9]{7})')"))
new.show()
+-------+
|COLUMN1|
+-------+
|1057873|
|1057887|
|1312039|
|1463451|
|1463485|
|1617275|
|1617288|
+-------+
我有一个如下所示的 Pyspark 数据框,需要创建一个新的数据框,其中只有一列由原始数据框中的所有 7 位数字组成。这些值都是字符串。 Column1 应该被忽略。忽略 Column2 中的非数字和单个 7 位数字非常简单,但是对于具有两个单独的 7 位数字的值,我很难将它们单独提取出来。这需要自动化并能够 运行 在其他类似的数据帧上。这些数字始终为 7 位数字,并且始终以“1”开头。有什么建议吗?
+-----------+--------------------+
| COLUMN1| COLUMN2|
+-----------+--------------------+
| Value1| Something|
| Value2| 1057873 1057887|
| Value3| Something Something|
| Value4| null|
| Value5| 1312039|
| Value6| 1463451 1463485|
| Value7| Not In Database|
| Value8| 1617275 1617288|
+-----------+--------------------+
生成的数据框应如下所示:
+-------+
|Column1|
+-------+
|1057873|
|1057887|
|1312039|
|1463451|
|1463485|
|1617275|
|1617288|
+-------+
- 更新:
反应很好,但不幸的是我使用的是不同意的旧版本 Spark。我用下面的方法解决了这个问题,虽然它有点笨拙......它有效。
from pyspark.sql import functions as F
new_df = df.select(df.COLUMN2)
new_df = new_df.withColumn('splits', F.split(new_df.COLUMN2, ' '))
new_df = new_df.select(F.explode(new_df.splits).alias('column1'))
new_df = new_df.filter(new_df.column1.rlike('\d{7}'))
IIUC,您可以使用正则表达式和 str.extractall
:
df2 = (df['COLUMN2'].str.extractall(r'(\b\d{7}\b)')[0]
.reset_index(drop=True).to_frame(name='COLUMN1')
)
输出:
COLUMN1
0 1057873
1 1057887
2 1312039
3 1463451
4 1463485
5 1617275
6 1617288
正则表达式:
( start capturing
\b word boundary
\d{7} 7 digits # or 1\d{6} for "1" + 6 digits
\b word boundary
) end capture
这是一种用于 spark 2.4+ 的高阶 lambda 函数的方法,其中我们按 space 拆分列,然后过滤以 0-9 开头且长度为 n (7) 的词,然后展开:
n = 7
df.selectExpr(f"""explode(filter(split(COLUMN2,' '),x->
x rlike '^[0-9]+' and length(x)={n})) as COLUMN1""").show(truncate=False)
+-------+
|COLUMN1|
+-------+
|1057873|
|1057887|
|1312039|
|1463451|
|1463485|
|1617275|
|1617288|
+-------+
我喜欢@nky 并投了票。替代方案也可以使用 pysparks 存在于 3.0+
的高阶函数中new = df.selectExpr("explode(split(COLUMN2,' ')) as COLUMN1").where(F.expr("exists(array(COLUMN1), element -> element rlike '([0-9]{7})')"))
new.show()
+-------+
|COLUMN1|
+-------+
|1057873|
|1057887|
|1312039|
|1463451|
|1463485|
|1617275|
|1617288|
+-------+