【问题标题】:Replace accounting notation for negative number with minus value用负值替换负数的会计符号
【发布时间】:2021-06-22 15:54:19
【问题描述】:

我有一个包含负数的数据框,带有会计符号,即:

df.select('sales').distinct().show()

+------------+
|    sales   |
+------------+
|         18 |
|          3 |
|         10 |
|         (5)|
|          4 |
|         40 |
|          0 |
|          8 |
|         16 |
|         (2)|
|          2 |
|         (1)|
|         14 |
|         (3)|
|          9 |
|         19 |
|         (6)|
|          1 |
|         (9)|
|         (4)|
+------------+
only showing top 20 rows

() 中的数字是负数。如何将它们替换为负值,即 (5) 变为 -5 等等。


这是我尝试过的:

sales = (
    df
    .select('sales')
    .withColumn('sales_new',
               sf.when(sf.col('sales').substr(1,1) == '(',
                       sf.concat(sf.lit('-'), sf.col('sales').substr(2,3)))
               .otherwise(sf.col('sales')))
    
)

sales.show(20,False)

+---------+---------+
|salees   |sales_new|
+---------+---------+
| 151     | 151     |
| 134     | 134     |
| 151     | 151     |
|(151)    |-151     |
|(134)    |-134     |
|(151)    |-151     |
| 151     | 151     |
| 50      | 50      |
| 101     | 101     |
| 134     | 134     |
|(134)    |-134     |
| 46      | 46      |
| 151     | 151     |
| 134     | 134     |
| 185     | 185     |
| 84      | 84      |
| 188     | 188     |
|(94)     |-94)     |
| 38      | 38      |
| 21      | 21      |
+---------+---------+

问题是销售的长度可能会有所不同,因此在某些情况下将值硬编码到 substring() 中不起作用。


我曾尝试使用regexp_replace,但收到以下错误:

PatternSyntaxException:索引 1 附近的未闭合组

sales = (
    df
    .select('sales')
    .withColumn('sales_new', regexp_replace(sf.col('sales'), '(', ''))
)

【问题讨论】:

标签: python-3.x apache-spark pyspark apache-spark-sql


【解决方案1】:

这可以通过case语句和正则表达式一起解决:

from pyspark.sql.functions import regexp_replace, col

sales = (
    df
    .select('sales')
    .withColumn('sales_new', sf.when(sf.col('sales').substr(1,1) == '(',
                sf.concat(sf.lit('-'), regexp_replace(sf.col('sales'), '\(|\)', '')))
                .otherwise(sf.col('sales')))
)

sales.show(20,False)

+---------+---------+
|sales    |sales_new|
+---------+---------+
|151      |151      |
|134      |134      |
|151      |151      |
|(151)    |-151     |
|(134)    |-134     |
|(151)    |-151     |
|151      |151      |
|50       |50       |
|101      |101      |
|134      |134      |
|(134)    |-134     |
|46       |46       |
|151      |151      |
|134      |134      |
|185      |185      |
|84       |84       |
|188      |188      |
|(94)     |-94      |
|38       |38       |
|21       |21       |
+---------+---------+

【讨论】:

    【解决方案2】:

    可以将字符串从倒数第二个字符切分,然后转换为浮点数,例如:

    def convert(number):
        try:
            number = float(number)
        except:
            
            number = number[1:-1]
            number = float(number)
            return number
    

    您可以遍历所有元素并应用此功能。

    【讨论】:

      猜你喜欢
      • 2019-06-10
      • 1970-01-01
      • 2018-06-24
      • 2012-07-01
      • 2015-04-26
      • 2015-12-31
      • 2020-12-16
      • 2015-10-16
      • 2012-05-07
      相关资源
      最近更新 更多