我正在使用pyspark 1.5.2。我有一个带有列“ ID”和“高度”的pyspark数据框,如下所示:
| ID1| ID2| height|
---------------------------------------------
| 1| 000| 44|
| 2| 000| 72.9|
| 3| 000| 89|
| 4| 000| 45.5|
| 5| 000| 52.3|
| 6| 000| 87.9|
| 7| 000| 63.1|
| 8| 000| 26.1|
| 9| 000| 97|
| 10| 000| 120|
| 11| 000| 99|
| 12| 000| 96|
| 13| 000| 36.5|
| 14| 000| 0|
| 15| 001| 48|
| 16| 001| 152.1|
| 17| 001| 72.2|
| 18| 001| 21.5|
| 19| 001| 94|
| 20| 001| 220|
+--------------+--------------+-------------+
我要计算每个“ ID2”的高度四分位数,并根据以下标准将其分为高,中或短四分之三:
Short: All height < Q1
Medium: All height within inclusive inter-quartile range (IQR) Q3-Q1
Tall: All height > Q3
我正在研究pyspark.sql模块,并找到了summary()函数,通过该函数可以计算四分位数范围,但它不适用于基于“ ID2”列的groupby。最终结果将是:
| ID1 | Height |
-------------------------
| 1| Tall|
| 2| Short|
| 3| Medium| and so on
我该怎么做?有更好的方法还是更简单的方法?
对此我还很陌生,将不胜感激!
提前谢谢!
答案 0 :(得分:1)
在处理函数中传递您的输入数据框,它将按照作者的意图返回输出数据框。 分位数功能会返回该范围内的两个值,并重新插入原始数据帧。然后可以在顶部运行比较器。
import pandas as pd
import numpy as np
def quantile(x):
x['first']= np.percentile(x['height'], 25)
x['third']= np.percentile(x['height'], 75)
return x
def process(input_df):
grouped_df = input_df.groupby(['ID2']).apply(quantile)
grouped_df.loc[(grouped_df.height >= grouped_df.first) & (grouped_df.height <= grouped_df.third), 'result'] = 'Medium'
grouped_df.loc[(grouped_df.height < grouped_df.first) , 'result'] = 'Short'
grouped_df.loc[ (grouped_df.height > grouped_df.third),'result'] = 'Tall'
return grouped_df
main_df = pd.read_csv('sample.csv')
print process(main_df)
答案 1 :(得分:1)
这是一种使用pyspark 1.5.2的无熊猫方法。 “ input_df”是此处的原始数据帧:
input_df.registerTempTable("input_df")
quartile_df = sqlContext.sql("select id2, percentile_approx(cast(height as decimal), 0.25) as Q1_value, percentile_approx(cast(height as decimal), 0.5) as Q2_value, percentile_approx(cast(height as decimal), 0.75) as Q3_value from input_df group by id2")
input_df=input_df.join(quartile_df, input_df.id2 == quartile_df.id2, 'left_outer')
input_df.select(F.when(input_df.height < input_df.Q1_value, 'short').when(input_df.height.between(input_df.Q1_value, input_df.Q3_value), 'medium').when(input_df.height > input_df.Q3_value, 'tall').alias('height_tag')).show()
以上代码基本上将input_df注册为临时表,并允许通过SQL查询。在查询中,使用percentile_approx给出Q1,Q2和Q3,分别为25%,50%和75%,最终将它们与原始数据帧结合在一起。在最终的LOC中,“ height”的每个值都根据条件分为短,中或高。
希望这会有所帮助