2017-12-28 49 views
0

PySpark DataFrame에서 중첩 된 데이터 products의 평균 및 표준 편차를 계산 중입니다.평균 및 표준 편차를 계산할 때 아무 값도 없음

+----------+--------------------------------+ 
|product_PK|      products| 
+----------+--------------------------------+ 
|  686 |   [[686,520.70],[645,2]]| 
|  685 |[[685,45.556],[678,23],[655,21]]| 
|  693 |        []| 

문제는 평균 및 표준 편차의 값으로 없음을 얻는 것입니다. 대부분 코드는 []을 고려하지 않기 때문에 발생합니다. 빈 값은 0으로 대체해야합니다. 또한 IntegerType은 아마 float 값이어야합니다.

없음 대신 올바른 결과를 얻으려면 어떻게해야합니까?

from pyspark.sql.types import IntegerType 
from pyspark.sql.functions import explode, col, udf, mean as mean_, stddev as stddev_ 

df = sqlCtx.createDataFrame(
    [(686, [[686,520.70], [645,2]]), (685, [[685,45.556], [678,23],[655,21]]), (693, [])], 
    ["product_PK", "products"] 
) 

get_score = udf(lambda x: x[1], IntegerType()) 

df_stats = df.withColumn('exploded', explode(col('products')))\ 
    .withColumn('score', get_score(col('exploded')))\ 
    .select(
     mean_(col('score')).alias('mean'), 
     stddev_(col('score')).alias('std') 
    )\ 
    .collect() 

mean = df_stats[0]['mean'] 
std = df_stats[0]['std'] 

print([mean, std]) 

답변

2

첫째, 당신은 단지

df.withColumn("exploded" , explode(col("products"))) 
    .withColumn("score", col("exploded").getItem(1)) 
    .na.fill(0) 
    .select( 
      mean_(col("score")).alias("mean") , 
      stddev_(col("score")).alias("stddev") 
     ) 
    .show() 

+----+------------------+ 
|mean|   stddev| 
+----+------------------+ 
| 9.2|11.734564329364767| 
+----+------------------+ 
(귀하의 경우 영) 숫자로 NULL 값을 채우기 위해 na.fill를 사용하여 배열

두 번째에서 항목을 가져 오기 위해 UDF가 필요하지 않습니다

변수에 별도의 값을 얻으려면 :

row = df.withColumn("exploded" , explode(col("products"))) 
     .withColumn("score", col("exploded").getItem(1)) 
     .na.fill(0) 
     .select( 
      mean_(col("score")).alias("mean") , 
      stddev_(col("score")).alias("stddev") 
     ) 
     .first() 

mean = row.mean 
stddev = row.stddev 
+0

이 좋아 매우 유용합니다. 0으로 채우지 않고 빈 값을 무시하려면 어떻게해야합니까? 그들을 삭제하는 쉬운 방법이 있습니까? – Markus

+0

계산을 진행하기 전에'na.fill (0)'을하는 대신'score is not null'을 필터링 할 수 있습니다. – philantrovert

+0

당신은 다음과 같은 것을 의미합니까? :'where (col ("score"). isNotNull())' – Markus