PySpark在各种列上获得不同的值

时间:2017-08-18 10:52:15

标签: apache-spark pyspark pyspark-sql

我的数据包含大量自定义列,其内容我很难理解。列名为evar1evar250。我想要获得的是一个包含所有不同值的表,并计算这些值发生的频率和列的名称。

------------------------------------------------ 
| columnname | value                 | count   |
|------------|-----------------------|---------|
| evar1      | en-GB                 | 7654321 |
| evar1      | en-US                 | 1234567 |
| evar2      | www.myclient.com      |     123 |
| evar2      | app.myclient.com      |     456 |
| ... 

我能想到这样做的最好方法感觉非常糟糕,因为我认为每列必须读取一次这个数据(实际上有大约400个这样的列。

i = 1
df_evars = None
while i <= 30:
  colname = "evar" + str(i)
  df_temp = df.groupBy(colname).agg(fn.count("*").alias("rows"))\
    .withColumn("colName", fn.lit(colname))
  if df_evars:
    df_evars = df_evars.union(df_temp)
  else:
    df_evars = df_temp
display(df_evars)

我错过了更好的解决方案吗?

更新

这已被标记为重复,但IMO的两个回复仅解决了我的部分问题。

我正在寻找可能具有大量值的非常宽的表。我需要一种简单的方法(即显示源列的3列,源列中值的值和计数。

第一个回复只给出了不同值的近似值。这对我来说毫无用处。

第二个反应似乎不如第一反应。为了澄清,源数据如下:

----------------------- 
| evar1 | evar2 | ... |
|---------------|-----|
| A     | A     | ... |
| B     | A     | ... |
| B     | B     | ... |
| B     | B     | ... |
| ... 

应该导致输出

--------------------------------
| columnname | value | count   |
|------------|-------|---------|
| evar1      | A     | 1       |
| evar1      | B     | 3       |
| evar2      | A     | 2       |
| evar2      | B     | 2       |
| ... 

1 个答案:

答案 0 :(得分:2)

使用从here借来的melt

from pyspark.sql.functions import col

melt(
    df.select([col(c).cast("string") for c in df.columns]), 
    id_vars=[], value_vars=df.columns
).groupBy("variable", "value").count()

改编自answeruser6910411