PySpark 通过从十进制列中删除比例来写入 csv

Posted

技术标签:

【中文标题】PySpark 通过从十进制列中删除比例来写入 csv【英文标题】:PySpark write to csv by removing scale from decimal columns 【发布时间】:2018-01-19 22:56:08 【问题描述】:

我想将数据框写入 CSV 文件,并在写入文件时删除比例值。如果比例是00,则与比例一起写。

例如,假设我有以下数据框。

+--------------+--------+--------+
|       id     |date    |amount  |
+--------------+--------+--------+
|12345678911.00|11/24/17|  203.02|
|12345678911.00|11/24/17|   13.52|
|12345678912.00|11/24/17|   28.00|
|12345678913.00|11/24/17|  105.71|
|12345678914.00|11/24/17|    7.68|
|12345678915.00|11/24/17|    0.18|
|12345678916.00|11/24/17|  530.38|
|12345678917.00|11/24/17|    1.79|
|12345678918.00|11/24/17|   35.00|
|12345678923.00|11/24/17|    8.84|
|12345678922.00|11/24/17|  150.47|
|12345678922.00|11/24/17|   39.00|
|12345678925.00|11/24/17|    6.46|
|12345678927.00|11/24/17|    2.59|
|12345678928.00|11/24/17|   25.00|
|12345678929.00|11/24/17|   44.04|
|12345678930.00|11/24/17|    3.90|
|12345678933.00|11/24/17|   50.00|
|12345678932.00|11/24/17|    6.26|
|12345678931.00|11/24/17|   10.90|
+--------------+--------+--------+

当我们写入 csv 文件时,输出应为所有十进制类型的列从每一行中删除 .00。 我们通过传递模式从 csv 读取值,其中我们定义了几列 DecimalType

预期的输出是。

+--------------+--------+--------+
|       id     |date    |amount  |
+--------------+--------+--------+
|12345678911   |11/24/17|  203.02|
|12345678911   |11/24/17|   13.52|
|12345678912   |11/24/17|      28|
|12345678913   |11/24/17|  105.71|
|12345678914   |11/24/17|    7.68|
|12345678915   |11/24/17|    0.18|
|12345678916   |11/24/17|  530.38|
|12345678917   |11/24/17|    1.79|
|12345678918   |11/24/17|      35|
|12345678923   |11/24/17|    8.84|
|12345678922   |11/24/17|  150.47|
|12345678922   |11/24/17|      39|
|12345678925   |11/24/17|    6.46|
|12345678927   |11/24/17|    2.59|
|12345678928   |11/24/17|      25|
|12345678929   |11/24/17|   44.04|
|12345678930   |11/24/17|    3.90|
|12345678933   |11/24/17|      50|
|12345678932   |11/24/17|    6.26|
|12345678931   |11/24/17|   10.90|
+--------------+--------+--------+ 

我尝试将其转换为 StringType,但没有多大帮助。 欢迎提出任何建议。

【问题讨论】:

【参考方案1】:

regexp_replace 替换结果并将输出写为字符串是你能得到的最接近的东西:

from pyspark.sql.functions import regexp_replace

df = spark.createDataFrame(
    [("203.02", ), ("0.18", ), ("3", ), ("10.90", )],
    ("amount", )
).withColumn("amount", col("amount").cast("decimal(38, 2)"))

df.select(regexp_replace("amount", "\\.00$", "")).show()
#+-------------------------------+
#|regexp_replace(amount, \.00$, )|
#+-------------------------------+
#|                         203.02|
#|                           0.18|
#|                              3|
#|                          10.90|
#+-------------------------------+

【讨论】:

也可以去掉额外的零,即代替10.90,我想将其保存为10.9。 ? "(\\.00$|(?<=\\.[1-9])0)"?

以上是关于PySpark 通过从十进制列中删除比例来写入 csv的主要内容,如果未能解决你的问题,请参考以下文章

从 pyspark 列中删除十进制值

Pyspark 通过使用另一列中的值替换 Spark 数据框列中的字符串

pyspark:数据框在另一个数据框的列中按ID选择行

如何通过从 CloudFormation 中删除来从 DynamoDb 中删除全局二级索引?

通过从每一行的不同列中选择一个元素,从 Pandas DataFrame 创建一个系列

通过从 SQL Server 中的当前日期删除超过 180 天的所有记录来清除