python结果列对象中的子字符串不可调用

2024-04-18 23:04:52 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在研究Pyspark,创建了一个带有一些长列和十进制类型列的示例数据框架。 在这里,我想在不舍入的情况下将十进制类型的列值提取到两个小数点。下面是我试过的代码

df = spark.createDataFrame([
  (324.456, "hi", "test"),
  (453.987, "hello", "python"),
  (768.66, "test", "java")
  ], ["col1", "col2", "col3"]
)
new = df.withColumn(
 "col4",
 F.substring((df.col1).cast(StringType()),1,F.instr((df.col1).cast(StringType()),".")+2))

所以在这里,我将列转换为字符串,并找到索引位置加上2(因为我需要两个小数点而不需要四舍五入)。但是我不知道这里有什么错误,我得到了Column对象不是可调用的错误。如果我只使用F.instr()函数,它就可以正常工作。请帮助我的另一个解决方案2,将值取到两位小数而不舍入

Expected output
col1     col2   col3   col4
324.456  hi     test   324.45
453.987  hello  python 453.98
768.66   test   java   768.66

Tags: test类型hellodf错误javahicol2
2条回答

你要找的是一种截断小数的方法。我建议您使用pyspark.sql.functions.pow和一些巧妙的使用强制转换来LongType实现这一点。通过这种方式,您可以乘以10^{decimal_places}再除以相同的数,同时强制转换到long以消除中间的小数(浮点),例如:

df2.show()
+   -+  -+   +
|   col1| col2|  col3|
+   -+  -+   +
|324.456|   hi|  test|
|453.987|hello|python|
| 768.66| test|  java|
+   -+  -+   +


decimal_places = 2
truncated_value_column = f.pow(f.lit(10), decimal_places).cast('long')

df2.withColumn(
    "trunc", 
    ((f.col("col1") * truncated_value_column)).cast("long") / truncated_value_column
).show()
+   -+  -+   +   +
|   col1| col2|  col3| trunc|
+   -+  -+   +   +
|324.456|   hi|  test|324.45|
|453.987|hello|python|453.98|
| 768.66| test|  java|768.66|
+   -+  -+   +   +

注意:如果你想回到string,我建议你以后再这样做。希望这有帮助

您还可以在此处使用带有regexp_extract的正则表达式:

df.withColumn('test',
              F.regexp_extract(F.col("col1").cast("string"),'\d+[.]\d{2}',0)).show()

或如@MohammadMurtazaHashmi在评论中所建议的,无需铸造:

df.withColumn('test',F.regexp_extract(F.col("col1"),'\d+[.]\d{2}',0)).show()

+   -+  -+   +   +
|   col1| col2|  col3|  test|
+   -+  -+   +   +
|324.456|   hi|  test|324.45|
|453.987|hello|python|453.98|
| 768.66| test|  java|768.66|
+   -+  -+   +   +

相关问题 更多 >