2015-05-01 10 views
25

ich einige Daten mit pyspark Datenrahmen bin Analyse an, dass habe ich einen Datenrahmen df, dass ich Aggregieren bin:Umbenennung Spalten für pyspark Datenrahmen Aggregate

df.groupBy("group")\ 
    .agg({"money":"sum"})\ 
    .show(100) 

Das gibt mir:

group    SUM(money#2L) 
A     137461285853 
B     172185566943 
C     271179590646 

die Aggregation funktioniert gut, aber ich mag den neuen Spaltennamen "SUM (Geld # 2L)" nicht. Gibt es eine nette Möglichkeit, diese Spalte in eine von der Methode .agg lesbare Form umzubenennen? Vielleicht etwas mehr ähnlich zu dem, was man in dplyr tun würde:

df %>% group_by(group) %>% summarise(sum_money = sum(money)) 

Antwort

43

Obwohl ich dplyr Syntax noch bevorzugen, wird dieser Code-Schnipsel tun:

import pyspark.sql.functions as sf 

df.groupBy("group")\ 
    .agg(sf.sum('money').alias('money'))\ 
    .show(100) 

Es ausführliche bekommt.

25

withColumnRenamed sollte es tun. Hier ist der Link zum pyspark.sql API.

df.groupBy("group")\ 
    .agg({"money":"sum"})\ 
    .withColumnRenamed("SUM(money)", "money") 
    .show(100) 
3

Ich habe eine kleine Hilfsfunktion dafür gemacht, die einigen Leuten helfen könnte.

import re 

from functools import partial 

def rename_cols(agg_df, ignore_first_n=1): 
    """changes the default spark aggregate names `avg(colname)` 
    to something a bit more useful. Pass an aggregated dataframe 
    and the number of aggregation columns to ignore. 
    """ 
    delimiters = "(", ")" 
    split_pattern = '|'.join(map(re.escape, delimiters)) 
    splitter = partial(re.split, split_pattern) 
    split_agg = lambda x: '_'.join(splitter(x))[0:-ignore_first_n] 
    renamed = map(split_agg, agg_df.columns[ignore_first_n:]) 
    renamed = zip(agg_df.columns[ignore_first_n:], renamed) 
    for old, new in renamed: 
     agg_df = agg_df.withColumnRenamed(old, new) 
    return agg_df 

Ein Beispiel:

gb = (df.selectExpr("id", "rank", "rate", "price", "clicks") 
.groupby("id") 
.agg({"rank": "mean", 
     "*": "count", 
     "rate": "mean", 
     "price": "mean", 
     "clicks": "mean", 
     }) 
) 

>>> gb.columns 
['id', 
'avg(rate)', 
'count(1)', 
'avg(price)', 
'avg(rank)', 
'avg(clicks)'] 

>>> rename_cols(gb).columns 
['id', 
'avg_rate', 
'count_1', 
'avg_price', 
'avg_rank', 
'avg_clicks'] 

mindestens Doing ein wenig Leute sparen so viel tippen.

+0

Sehr nützlich und zeitnah. Ich wollte gerade die gleiche Frage stellen. Es wäre schön, wenn Sie einen neuen Spaltennamen innerhalb des 'agg'-Diktats angeben könnten (innerhalb von Spark I mean). –

+0

@EvanZamir danke! Ich könnte versuchen, eine einfache PR in Funken dafür zu machen. –

Verwandte Themen