Python 如何在SQL和pandas中获得相同的百分比排名?

Python 如何在SQL和pandas中获得相同的百分比排名?,python,sql,pandas,pyspark,hiveql,Python,Sql,Pandas,Pyspark,Hiveql,我正在学习使用HiveQL的pyspark,并发现有趣的是,百分比排名为pyspark-sql和pandas提供了两种不同的答案 问题源代码与sql代码: 如何在pandas中获得与SQL相同的结果 两个问题 给出与SQL相同结果的python代码是什么 什么样的SQL代码会给出与pandas相同的结果 pysparksql q=”“” 选择名称、重量、, 百分比(按重量排序)作为百分比(按重量排序) 来自猫 按重量订购 """ spark.sql(q.show()) SQL给出了这个表。我

我正在学习使用HiveQL的
pyspark
,并发现有趣的是,百分比排名为
pyspark-sql
pandas
提供了两种不同的答案

问题源代码与sql代码:

如何在pandas中获得与SQL相同的结果

两个问题
  • 给出与SQL相同结果的python代码是什么
  • 什么样的SQL代码会给出与pandas相同的结果
pysparksql
q=”“”
选择名称、重量、,
百分比(按重量排序)作为百分比(按重量排序)
来自猫
按重量订购
"""
spark.sql(q.show())
SQL给出了这个表。我想要同一张用熊猫做的桌子。
+-------+------+-------------------+
|名称|重量|百分比|等级|重量|
+-------+------+-------------------+
|跳跳虎| 3.8 | 0.0|
|莫莉| 4.2 | 0.091|
|灰烬| 4.5 | 0.18182|
|查理| 4.8 | 0.2727|
|污迹| 4.9 | 0.36365|
|费利克斯| 5.0 | 0.453|
|Puss | 5.1 | 0.5454|
|米莉| 5.4 | 0.6364|
|阿尔菲| 5.5 | 0.7273|
|薄雾| 5.7 | 0.8182|
|奥斯卡| 6.1 | 0.9091|
|Smokey | 6.1 | 0.9091|
+-------+------+-------------------+
熊猫
methods={'average','min','max','first','dense'}
df[['name','weight']]。对值(“weight”)进行排序。分配(
pct_avg=df['weight'].秩(pct=True,method='average'),
pct_min=df['weight'].秩(pct=True,method='min'),
pct_max=df['weight'].秩(pct=True,method='max'),
pct_first=df['weight'].rank(pct=True,method='first'),
pct_densite=df['weight'].秩(pct=True,method='densite')
).sort_值(“权重”)
名称重量平均重量最小重量最大重量第一重量密度
4跳跳虎3.8 0.083333 0.083333 0.083333 0.083333 0.090909
0莫莉4.2 0.166667 0.166667 0.166667 0.166667 0.166667 0.181818
1灰烬4.50.250000.250000.250000.250000.250000.2727
11查理4.8 0.333333 0.333333 0.333333 0.333333333 0.363636
3涂抹4.9 0.416667 0.416667 0.416667 0.416667 0.416667 0.454545
2 Felix 5.0 0.500000 0.500000 0.500000 0.545455
9 Puss 5.1 0.583333 0.583333 0.583333 0.583333 0.636364
7毫埃5.4 0.666667 0.666667 0.666667 0.666667 0.666667 0.727273
5阿尔菲5.50.750000 0.750000 0.750000 0.750000 0.818182
8薄雾5.7 0.833333 0.833333 0.833333 0.833333 0.909091
6奥斯卡6.1 0.958333 0.916667 1.000000 0.916667 1.000000
10 Smokey 6.1 0.958333 0.916667 1.000000 1.000000 1.000000
设置
将numpy导入为np
作为pd进口熊猫
进口Pypark
从pyspark.sql.types导入*
从pyspark.sql导入函数为F
从pyspark.sql.window导入窗口
从pyspark导入SparkConf、SparkContext、SQLContext
spark=pyspark.sql.SparkSession.builder.appName('app').getOrCreate()
sc=spark.sparkContext
sqlContext=sqlContext(sc)
df=pd.DataFrame({
“姓名”:[
“莫莉”、“灰烬”、“菲利克斯”、“斯玛奇”、“跳跳虎”、“阿尔菲”、“奥斯卡”,
“米莉”、“米丝蒂”、“猫咪”、“斯莫奇”、“查理”
],
“品种”:[
“波斯语”、“波斯语”、“波斯语”、“英国短发”,
“英国短发”、“暹罗人”、“暹罗人”、“缅因州浣熊”、“缅因州浣熊”,
“缅因库恩”,“缅因库恩”,“英国短发”
],
“重量”:[4.2,4.5,5.0,4.9,3.8,5.5,6.1,5.4,5.7,5.1,6.1,4.8],
“颜色”:[
‘黑色’、‘黑色’、‘龟甲’、‘黑色’、‘龟甲’、‘棕色’,
“黑色”、“玳瑁”、“棕色”、“玳瑁”、“棕色”、“黑色”
],
‘年龄’:[1,5,2,4,2,5,1,5,2,2,4,4]
})
schema=StructType([
StructField('name',StringType(),True),
StructField('bride',StringType(),True),
StructField('weight',DoubleType(),True),
StructField('color',StringType(),True),
StructField('age',IntegerType(),True),
])
sdf=sqlContext.createDataFrame(df,schema)
sdf.createOrReplaceTempView(“猫”)

SQL的
百分比等级
与pandas的
等级
不完全相同。主要有两个区别:

  • SQL的
    百分比排名将当前行从计算中排除。因此,如果表有11行,则每行只使用其他10行计算结果。熊猫
    rank
    包括所有行
  • SQL的
    percent\u rank
    给出了严格小于当前行的行数。pandas
    rank
    不支持这样做的方法
给出与SQL相同结果的python代码是什么? 要获得pandas中SQL的
percent_rank
,您实际上可以对
rank
结果执行一个小计算:

(df['weight'].rank(method='min')-1) / (len(df['weight'])-1)
分子中的
-1
用于获得严格小于当前行的行数,分母中的
-1
用于计算不包括当前行的结果

什么样的SQL代码会给出与pandas相同的结果?
这取决于您在pandas
rank
中使用的方法,但您可能需要。

在问题中,我给出了SQL代码的输出。我的python代码给出了不同的结果。这意味着我的python代码是错误的。我希望有一个“正确”的python代码,它能给出与SQL代码相同的结果(
percent\u rank
)。你能添加一个方法densite
.rank(pct=True,method='densite')
?仍然给出不同的答案。看起来
pct\u densite
是1
shift
,离那里差不多:)