Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/flash/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Dataframe 通过遍历列表替换pyspark中的列值_Dataframe_Apache Spark_Pyspark_Apache Spark Sql - Fatal编程技术网

Dataframe 通过遍历列表替换pyspark中的列值

Dataframe 通过遍历列表替换pyspark中的列值,dataframe,apache-spark,pyspark,apache-spark-sql,Dataframe,Apache Spark,Pyspark,Apache Spark Sql,我有一个pyspark数据帧作为 | ID|colA|colB |colC| +---+----+-----+----+ |ID1| 3|5.85 | LB| |ID2| 4|12.67| RF| |ID3| 2|20.78| LCM| |ID4| 1| 2 | LWB| |ID5| 6| 3 | LF| |ID6| 7| 4 | LM| |ID7| 8| 5 | RS| +---+----+----+----+ 我的目标是将ColC中的值

我有一个pyspark数据帧作为

| ID|colA|colB |colC|
+---+----+-----+----+
|ID1|   3|5.85 |  LB|
|ID2|   4|12.67|  RF|
|ID3|   2|20.78| LCM|
|ID4|   1|   2 | LWB|
|ID5|   6|   3 |  LF|
|ID6|   7|   4 |  LM|
|ID7|   8|   5 |  RS|
+---+----+----+----+
我的目标是将ColC中的值替换为LB、LWB、LF的值,如下所示

x = [LB,LWB,LF]
y = [RF,LCM]
z = [LM,RS]
目前,我可以通过手动替换以下代码中的每个值来实现这一点:

# Replacing the values LB,LWF,LF with x

df_new = df.withColumn('ColC',f.when((f.col('ColC') == 'LB')|(f.col('ColC') == 'LWB')|(f.col('ColC') == 'LF'),'x').otherwise(df.ColC))
我这里的问题是,我们如何通过使用pyspark动态地一次迭代列表(x,y,z)来替换列的值(在我的示例中是ColC)?所涉及的时间复杂度是多少?此外,我们如何将ColB中的十进制值截断为1个十进位?

您可以在dataframe上通过传递映射的dict对象来替换
colC中的值。和
round
函数,用于限制
colB
中的小数位数:

from pyspark.sql import functions as F

replacement = {
    "LB": "x", "LWB": "x", "LF": "x",
    "RF": "y", "LCM": "y",
    "LM": "z", "RS": "z"
}

df1 = df.replace(replacement, ["colC"]).withColumn("colB", F.round("colB", 1))

df1.show()

#+---+----+----+----+
#| ID|colA|colB|colC|
#+---+----+----+----+
#|ID1|   3| 5.9|   x|
#|ID2|   4|12.7|   y|
#|ID3|   2|20.8|   y|
#|ID4|   1| 2.0|   x|
#|ID5|   6| 3.0|   x|
#|ID6|   7| 4.0|   z|
#|ID7|   8| 5.0|   z|
#+---+----+----+----+
通过传递映射的dict对象,可以使用on dataframe替换
colC
中的值。和
round
函数,用于限制
colB
中的小数位数:

from pyspark.sql import functions as F

replacement = {
    "LB": "x", "LWB": "x", "LF": "x",
    "RF": "y", "LCM": "y",
    "LM": "z", "RS": "z"
}

df1 = df.replace(replacement, ["colC"]).withColumn("colB", F.round("colB", 1))

df1.show()

#+---+----+----+----+
#| ID|colA|colB|colC|
#+---+----+----+----+
#|ID1|   3| 5.9|   x|
#|ID2|   4|12.7|   y|
#|ID3|   2|20.8|   y|
#|ID4|   1| 2.0|   x|
#|ID5|   6| 3.0|   x|
#|ID6|   7| 4.0|   z|
#|ID7|   8| 5.0|   z|
#+---+----+----+----+

您还可以使用isin功能:

from pyspark.sql.functions import col, when

x = ['LB','LWB','LF']
y = ['LCM','RF']
z = ['LM','RS']

df = df.withColumn('ColC', when(col('colC').isin(x), "x")\
                  .otherwise(when(col('colC').isin(y), "y")\
                  .otherwise(when(col('colC').isin(z), "z")\
                  .otherwise(df.ColC))))

如果您有几个列表中的值太多,那么您的复杂性比Blackishop答案要小,但在这个问题上,他的答案更简单。

您还可以使用isin函数:

from pyspark.sql.functions import col, when

x = ['LB','LWB','LF']
y = ['LCM','RF']
z = ['LM','RS']

df = df.withColumn('ColC', when(col('colC').isin(x), "x")\
                  .otherwise(when(col('colC').isin(y), "y")\
                  .otherwise(when(col('colC').isin(z), "z")\
                  .otherwise(df.ColC))))

如果你有几个列表中有太多的值,那么你的复杂性比Blackishop答案要小,但在这个问题上他的答案更容易。

如果你有很多条件要匹配,你可以
合并
when
语句。您还可以使用字典保存要转换的列,并使用dict理解动态构造
when
语句。至于四舍五入到小数点后1位,您可以使用
round

import pyspark.sql.functions as F

xyz_dict = {'x': ['LB','LWB','LF'],
            'y': ['RF','LCM'],
            'z': ['LM','RS']}

df2 = df.withColumn(
    'colC',
    F.coalesce(*[F.when(F.col('colC').isin(v), k) for (k, v) in xyz_dict.items()])
).withColumn(
    'colB',
    F.round('colB', 1)
)

df2.show()
+---+----+----+----+
| ID|colA|colB|colC|
+---+----+----+----+
|ID1|   3| 5.9|   x|
|ID2|   4|12.7|   y|
|ID3|   2|20.8|   y|
|ID4|   1| 2.0|   x|
|ID5|   6| 3.0|   x|
|ID6|   7| 4.0|   z|
|ID7|   8| 5.0|   z|
+---+----+----+----+

如果有许多条件需要匹配,则可以
合并
when
语句。您还可以使用字典保存要转换的列,并使用dict理解动态构造
when
语句。至于四舍五入到小数点后1位,您可以使用
round

import pyspark.sql.functions as F

xyz_dict = {'x': ['LB','LWB','LF'],
            'y': ['RF','LCM'],
            'z': ['LM','RS']}

df2 = df.withColumn(
    'colC',
    F.coalesce(*[F.when(F.col('colC').isin(v), k) for (k, v) in xyz_dict.items()])
).withColumn(
    'colB',
    F.round('colB', 1)
)

df2.show()
+---+----+----+----+
| ID|colA|colB|colC|
+---+----+----+----+
|ID1|   3| 5.9|   x|
|ID2|   4|12.7|   y|
|ID3|   2|20.8|   y|
|ID4|   1| 2.0|   x|
|ID5|   6| 3.0|   x|
|ID6|   7| 4.0|   z|
|ID7|   8| 5.0|   z|
+---+----+----+----+

您也可以使用regexp\u replace尝试使用正则表达式:

import pyspark.sql.functions as f

replacements = [
    ("(LB)|(LWB)|(LF)", "x"),
    ("(LCM)|(RF)", "y"),
    ("(LM)|(RS)", "z")
]
for x, y in replacements:
    df = df.withColumn("colC", f.regexp_replace("colC", x, y))

您也可以使用regexp\u replace尝试使用正则表达式:

import pyspark.sql.functions as f

replacements = [
    ("(LB)|(LWB)|(LF)", "x"),
    ("(LCM)|(RF)", "y"),
    ("(LM)|(RS)", "z")
]
for x, y in replacements:
    df = df.withColumn("colC", f.regexp_replace("colC", x, y))