【问题标题】:How to count how many uppercase & lowercase strings are within an array column of a given id如何计算给定id的数组列中有多少个大写和小写字符串
【发布时间】:2021-05-16 07:46:41
【问题描述】:

我的数据如下所示:

|  date      |     id       |    name    |  version  |                              assetIDs                               |
|------------| -------------| -----------|-----------|---------------------------------------------------------------------| 
| 2021-02-11 | com.example1 |   example1 |   1.2.3   |["4er6d99j","43mdmdm","234ds234","w23432s","sdfdsfds","32erwer"]    |
| 2021-02-11 | com.example2 |   example2 |   2.3.4   |["3er6d99j","43mdmdm","MMMM234","werewer","MMM3333","dssdsssM"]      |
| 2021-02-11 | com.example3 |   example3 |   2.3.4   |["3er6d99j","43mdmdm","MMMM234","YYYY2222","mmmm3444","yy2222"]      |
| 2021-02-11 | com.example4 |   example4 |   2.3.4   |["3er6d99j","43mdmdm","MMMM234","222sdsss","fffff3333","ffffffff"]   |
| 2021-02-11 | com.example5 |   example5 |   2.3.4   |["3er6d99j","43mdmdm","MMMM234","Y222222","YYYYJJJJ2222","DJDDJSJ2"] |
| 2021-02-11 | com.example6 |   example6 |   2.3.4   |["3er6d99j","43mdmdm","MMMM234","Ydddddd","ssdfdfdfd","sdfdwsfw"]    |

根据assetIDs 中的字符串,我需要能够再拥有两列,一列lowerCaseCount,一列upperCaseCount

最终结果将是两个额外的列,每个 id 中包含小写和大写字符串数量。

我已经开始这样做了,但这并没有给我预期的结果:

with data as (
      select date, id, name, version, explode(assetIDs) as assetids 
      from assets_table 
)

select dt.data, dt.id, dt.name dt.version, count(UPPER(assetids)) as upperCount,  count(LOWER(assetids)) as lowerCount, as.assetids
        from data dt
        inner join assets_table as on dt.id = as.id
        group by 1,2,3,4,7

这只是返回字符串的数量,所以大写和小写列的总数

我怎样才能以最好的方式做到这一点?我可以在 Scala、Python 或/和使用 SQL 中做到这一点,就像我使用 databricks 一样。

【问题讨论】:

    标签: scala apache-spark pyspark apache-spark-sql


    【解决方案1】:

    您可以进行条件聚合。我不确定你想如何处理大小写混合的字符串。

    df2 = df.selectExpr(
        "*",
        "aggregate(assetIDs, 0, (acc, x) -> acc + case when lower(x) = x then 1 else 0 end) as lowerCaseCount",
        "aggregate(assetIDs, 0, (acc, x) -> acc + case when upper(x) = x then 1 else 0 end) as upperCaseCount"
    )
    
    df2.show(truncate=False)
    +----------+------------+--------+-------+-------------------------------------------------------------+--------------+--------------+
    |date      |id          |name    |version|assetIDs                                                     |lowerCaseCount|upperCaseCount|
    +----------+------------+--------+-------+-------------------------------------------------------------+--------------+--------------+
    |2021-02-11|com.example1|example1|1.2.3  |[4er6d99j, 43mdmdm, 234ds234, w23432s, sdfdsfds, 32erwer]    |6             |0             |
    |2021-02-11|com.example2|example2|2.3.4  |[3er6d99j, 43mdmdm, MMMM234, werewer, MMM3333, dssdsssM]     |3             |2             |
    |2021-02-11|com.example3|example3|2.3.4  |[3er6d99j, 43mdmdm, MMMM234, YYYY2222, mmmm3444, yy2222]     |4             |2             |
    |2021-02-11|com.example4|example4|2.3.4  |[3er6d99j, 43mdmdm, MMMM234, 222sdsss, fffff3333, ffffffff]  |5             |1             |
    |2021-02-11|com.example5|example5|2.3.4  |[3er6d99j, 43mdmdm, MMMM234, Y222222, YYYYJJJJ2222, DJDDJSJ2]|2             |4             |
    |2021-02-11|com.example6|example6|2.3.4  |[3er6d99j, 43mdmdm, MMMM234, Ydddddd, ssdfdfdfd, sdfdwsfw]   |4             |1             |
    +----------+------------+--------+-------+-------------------------------------------------------------+--------------+--------------+
    

    另一种计数方式:

    df2 = df.selectExpr(
        "*",
        "aggregate(assetIDs, 0, (acc, x) -> acc + case when x rlike '[a-z]' then 1 else 0 end) as lowerCaseCount",
        "aggregate(assetIDs, 0, (acc, x) -> acc + case when x rlike '[A-Z]' then 1 else 0 end) as upperCaseCount"
    )
    
    df2.show(truncate=False)
    +----------+------------+--------+-------+-------------------------------------------------------------+--------------+--------------+
    |date      |id          |name    |version|assetIDs                                                     |lowerCaseCount|upperCaseCount|
    +----------+------------+--------+-------+-------------------------------------------------------------+--------------+--------------+
    |2021-02-11|com.example1|example1|1.2.3  |[4er6d99j, 43mdmdm, 234ds234, w23432s, sdfdsfds, 32erwer]    |6             |0             |
    |2021-02-11|com.example2|example2|2.3.4  |[3er6d99j, 43mdmdm, MMMM234, werewer, MMM3333, dssdsssM]     |4             |3             |
    |2021-02-11|com.example3|example3|2.3.4  |[3er6d99j, 43mdmdm, MMMM234, YYYY2222, mmmm3444, yy2222]     |4             |2             |
    |2021-02-11|com.example4|example4|2.3.4  |[3er6d99j, 43mdmdm, MMMM234, 222sdsss, fffff3333, ffffffff]  |5             |1             |
    |2021-02-11|com.example5|example5|2.3.4  |[3er6d99j, 43mdmdm, MMMM234, Y222222, YYYYJJJJ2222, DJDDJSJ2]|2             |4             |
    |2021-02-11|com.example6|example6|2.3.4  |[3er6d99j, 43mdmdm, MMMM234, Ydddddd, ssdfdfdfd, sdfdwsfw]   |5             |2             |
    +----------+------------+--------+-------+-------------------------------------------------------------+--------------+--------------+
    

    【讨论】:

      【解决方案2】:

      您可以结合 sizefilter 函数来获取计数:

      spark.sql("""
           SELECT *, 
                  size(filter(assetIDs, x -> x = lower(x))) as lowerCaseCount,
                  size(filter(assetIDs, x -> x = upper(x))) as upperCaseCount
           FROM   assets_table
      """).show(truncate=False)
      
      #+----------+------------+--------+-------+-------------------------------------------------------------+--------------+--------------+
      #|date      |id          |name    |version|assetIDs                                                     |lowerCaseCount|upperCaseCount|
      #+----------+------------+--------+-------+-------------------------------------------------------------+--------------+--------------+
      #|2021-02-11|com.example1|example1|1.2.3  |[4er6d99j, 43mdmdm, 234ds234, w23432s, sdfdsfds, 32erwer]    |6             |0             |
      #|2021-02-11|com.example2|example2|2.3.4  |[3er6d99j, 43mdmdm, MMMM234, werewer, MMM3333, dssdsssM]     |3             |2             |
      #|2021-02-11|com.example3|example3|2.3.4  |[3er6d99j, 43mdmdm, MMMM234, YYYY2222, mmmm3444, yy2222]     |4             |2             |
      #|2021-02-11|com.example4|example4|2.3.4  |[3er6d99j, 43mdmdm, MMMM234, 222sdsss, fffff3333, ffffffff]  |5             |1             |
      #|2021-02-11|com.example5|example5|2.3.4  |[3er6d99j, 43mdmdm, MMMM234, Y222222, YYYYJJJJ2222, DJDDJSJ2]|2             |4             |
      #|2021-02-11|com.example6|example6|2.3.4  |[3er6d99j, 43mdmdm, MMMM234, Ydddddd, ssdfdfdfd, sdfdwsfw]   |4             |1             |
      #+----------+------------+--------+-------+-------------------------------------------------------------+--------------+--------------+
      

      或使用 DataFrame API:

      from pyspark.sql import functions as F
      
      df1 = df.withColumn("lowerCaseCount", F.expr("size(filter(assetIDs, x -> x = lower(x)))"))\
          .withColumn("upperCaseCount", F.expr("size(filter(assetIDs, x -> x = upper(x)))"))
      
      df1.show(truncate=False)
      

      【讨论】:

        猜你喜欢
        • 2015-06-04
        • 1970-01-01
        • 2015-02-10
        • 2014-10-03
        • 1970-01-01
        • 2020-01-04
        • 2017-08-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多