Pyspark将列除以小计,再由另一列分组

时间:2019-04-14 13:14:20

标签: python apache-spark dataframe pyspark calculated-field

我的问题类似于thisthis。这两个帖子都显示了如何将列值除以同一列的总和。就我而言,我想将一列的值除以小计的总和。通过汇总列值取决于另一列来计算小计。我对上面共享的链接中提到的示例进行了稍微的修改。

这是我的数据框

id_role

我想将“消费”值除以分组的“类别”的总和,然后将该值放在“标准化”列中,如下所示。

小计不需要在输出中(列消耗量的数字21、42和30) enter image description here

到目前为止我已经取得的成就 df.crossJoin(

<?php
session_start();

$Nom = $_POST["Nom"];
$mdp = $_POST["mdp"];
//$id_role = $_POST["id_role"];

try{
    $bdd = new PDO('mysql:host=localhost;dbname=azer', 'root', '', array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
} catch(Exception $e) {
    die("acces imlpossible");
}

$st = $bdd->query("SELECT * FROM membre WHERE Nom='".$Nom."'")->fetch();
$mangetesmorts = $bdd->query("SELECT * FROM membre WHERE id_role");

if (password_verify($mdp, $st['mdp'])) {
    $_SESSION['Nom'] = $Nom;
    $_SESSION['activite'] = $st['activite'];    //$_SESSION['id_role'] = $mangetesmorts['id_role'];
    //var_dump($_SESSION['id_role']);

    //print_r($id_role);
    while ($donne = $mangetesmorts->fetch()) {
        if ($_SESSION['activite'] =='cricket') {
            header("Location: cricket.php");
        } elseif ($_SESSION['activite'] == 'foot') {
            header("Location: foot.php");
        } elseif (($donne['id_role'] == 2)) {
            header("Location: admin.php");
        } elseif ($donne['id_role'] == 1) {
            header("Location: admin_super.php");
        } else {
            header("Location: index2.php");}
        }
   }

2 个答案:

答案 0 :(得分:1)

您可以执行与已提到的链接基本相同的操作。唯一的区别是,您必须先使用groupbysum计算小计:

import pyspark.sql.functions as F
df = df.join(df.groupby('category').sum('consumption'), 'category')
df = df.select('id', 'category', F.round(F.col('consumption')/F.col('sum(consumption)'), 2).alias('normalized'))
df.show()

输出:

+---+--------+----------+ 
| id|category|normalized| 
+---+--------+----------+ 
|  3|    CAT2|      0.48| 
|  4|    CAT2|      0.52| 
|  1|    CAT1|      0.48| 
|  2|    CAT1|      0.52| 
|  5|    CAT3|       1.0| 
+---+--------+----------+ 

答案 1 :(得分:1)

这是OP提出的另一种解决问题的方法,但不使用joins()

joins()通常是昂贵的操作,应尽可能避免。

# We first register our DataFrame as temporary SQL view
df.registerTempTable('table_view')
df = sqlContext.sql("""select id, category, 
                       consumption/sum(consumption) over (partition by category) as normalize
                       from table_view""")
df.show()
+---+--------+-------------------+
| id|category|          normalize|
+---+--------+-------------------+
|  3|    CAT2|0.47619047619047616|
|  4|    CAT2| 0.5238095238095238|
|  1|    CAT1|0.47619047619047616|
|  2|    CAT1| 0.5238095238095238|
|  5|    CAT3|                1.0|
+---+--------+-------------------+

注意: """用于显示多行语句是为了能见度和简洁。使用简单的'select id ....',如果您尝试将语句分散到多行上将无法使用。不用说,最终结果将是相同的。