PySpark - 如何在 csv 输出中删除科学记数法
Posted
技术标签:
【中文标题】PySpark - 如何在 csv 输出中删除科学记数法【英文标题】:PySpark - How to remove scientific notation in csv output 【发布时间】:2019-10-21 02:43:48 【问题描述】:我有一个 spark 聚合,我想将结果输出到 csv,但我发现 spark 总是以科学计数法输出大量小数。我已经尝试过this question 中提到的解决方案,但也没有用。
预期输出:
foo,avg(bar)
a,0.0000002
b,0.0000001
实际输出:
foo,avg(bar)
a,2.0E-7
b,1.0E-7
请参见下面的示例:
from os import path
import shutil
import glob
from pyspark.sql import SQLContext, functions as F, types
def test(sc):
sq = SQLContext(sc)
data = [("a", 1e-7), ("b", 1e-7), ("a", 3e-7)]
df = sq.createDataFrame(data, ['foo', 'bar'])
# 12 digits with 9 decimal places
decType = types.DecimalType(precision=12, scale=9)
# Cast both the column input and column output to Decimal
aggs = [F.mean(F.col("bar").cast(decType)).cast(decType)]
groups = [F.col("foo")]
result = df.groupBy(*groups).agg(*aggs)
write(result)
return df, aggs, groups, result
def write(result):
tmpDir = path.join("res", "tmp")
config = "sep": ","
result.write.format("csv")\
.options(**config)\
.save(tmpDir)
# Once the distributed portion is done, write out to a single a file
allFiles = glob.glob(path.join(tmpDir,"*.csv"))
fullOut = path.join("res", "final.csv")
with open(fullOut, 'wb') as wfd:
# First write out the header row
header = config.get("sep", ',').join(result.columns)
wfd.write(header + "\n")
for f in allFiles:
with open(f, 'rb') as fd:
shutil.copyfileobj(fd, wfd)
pass
pass
shutil.rmtree(tmpDir)
return
在 pyspark 外壳中:
import spark_test as t
t.test(sc)
【问题讨论】:
请添加当前输出和预期输出.. 【参考方案1】:>>> df1 = spark.createDataFrame([('a','2.0e-7'),('b','1e-5'),('c','1.0e-7')],['foo','avg'])
>>> df1.show()
+---+------+
|foo| avg|
+---+------+
| a|2.0e-7|
| b| 1e-5|
| c|1.0e-7|
+---+------+
>>> df1.select('foo','avg',format_string('%.7f',df1.avg.cast('float')).alias('converted')).show()
+---+------+---------+
|foo| avg|converted|
+---+------+---------+
| a|2.0e-7|0.0000002|
| b| 1e-5|0.0000100|
| c|1.0e-7|0.0000001|
+---+------+---------+
【讨论】:
有没有办法使用 format_string 删除尾随零? 当我将数据帧写入 csv 时,它仍然恢复为科学记数法 @thentangler 我还没有尝试过,但是如何再次将它们转换为字符串。【参考方案2】:您是否尝试将聚合结果转换为String
?这样一来,excel 就不会将该值识别为十进制,因此不会给出科学记数法表示。
【讨论】:
我没有。您介意提供一个工作示例吗?以上是关于PySpark - 如何在 csv 输出中删除科学记数法的主要内容,如果未能解决你的问题,请参考以下文章
在 PySpark 中将数据帧写入 CSV 后重命名文件 [重复]