pyspark count列中的非空值

时间:2018-02-05 21:50:14

标签: apache-spark null pyspark

我有一个包含空值的数据框:

data = [
 (125, '2012-10-10','tv'),
 (20, '2012-10-10','phone'),
 (40, '2012-10-10','tv'),
 ( None, '2012-10-10','tv')]

df = spark.createDataFrame(data, ["Sales", "date","product"])

我需要计算sales列中的Non Null值。 我尝试了3种方法: 第一个我做对了:

df.where(F.col("sales").isNotNull()).groupBy('product')\
.agg((F.count(F.col("Sales")).alias("sales_count"))).show()

我会得到

 product   | sales_count
 phone     |  1
 tv        |  2

第二个,它不正确:

df.groupBy('product')\
.agg((F.count(F.col("Sales").isNotNull()).alias("sales_count"))).show()

 product   | sales_count
 phone     |  1
 tv        |  3

第三个我收到错误:

 df.groupBy('product')\.agg((F.col("Sales").isNotNull().count()).alias("sales_count")).show()

 TypeError: 'Column' object is not callable

第二种和第三种方法可能导致错误的原因是什么? 感谢。

2 个答案:

答案 0 :(得分:1)

有一种更简单的方法:

<form id="HubForm" action="https://www.CRM-DOMAIN-NAME/Api/FormAdd" method="post">

  <input type="hidden" name="ClientId" value="123"><input type="hidden" name="FormTypeId" value="123">
  <input type="hidden" name="redirect" value="https://www.CLIENTS-DOMAIN-NAME.co.uk/applied/">

  <input id="firstname" class="emrform" name="firstname" type="text" placeholder="First Name" required /><br>

  <input id="lastname" class="emrform" name="lastname" type="text" placeholder="Last Name" required /><br>

  <input id="email" class="emrform" name="varchar3" type="text" placeholder="Phone number" required /><br>

  <input id="firstname" class="emrform" name="email" type="text" placeholder="Email" required /><br> Upload your CV<br><input id="fileUpload" class="emrform" name="fileUpload" type="file" accept=".pdf,.doc,.docx" /><br> Interested in receiving further
  emails?

  <br>
  <input type="radio" name="varchar4" value="yes" id="varchar4" checked> YES<br>
  <input type="radio" name="varchar4" value="no" id="varchar4"> no<br>
  <br>

  <br>
  <textarea class="emrform" id="textarea" rows="5" name="varchar2" placeholder="Message details..."></textarea>
  <br>

  <input type="submit" class="emrbtn emrbtn-primary" value="Submit"></form>
<div id="HubFormResult">

答案 1 :(得分:1)

您的第一次尝试是在进行聚合之前在null列中过滤掉Sales行。因此它给你正确的结果。

但是第二个代码

df.groupBy('product') \
    .agg((F.count(F.col("Sales").isNotNull()).alias("sales_count"))).show()

您没有filtered出来并在整个数据集上做过aggregation。如果你仔细分析F.col("Sales").isNotNull()会给你布尔列,即truefalse所以F.count(F.col("Sales").isNotNull())只是计算分组数据集中的布尔值,如果您创建一个新列,这很明显

df.withColumn("isNotNull", F.col("Sales").isNotNull()).show()

会给你

+-----+----------+-------+---------+
|Sales|      date|product|isNotNull|
+-----+----------+-------+---------+
|  125|2012-10-10|     tv|     true|
|   20|2012-10-10|  phone|     true|
|   40|2012-10-10|     tv|     true|
| null|2012-10-10|     tv|    false|
+-----+----------+-------+---------+

所以第二次尝试的计数是正确的。

对于您的第三次尝试,.count()是一项无法在聚合转换中使用的操作。 只有返回 dataType 的函数可以在.agg()中使用,并且它们可以内置函数 udf函数< / em>或您的自己的功能