df.groupby("key")["val"].sum()# single aggregationdf.groupby(["k1","k2"])["v"].agg(["mean","sum","count"])# single column aggregationdf.groupby("g").agg(total=("v","sum"),avg=("v","mean"))# named aggdf.groupby("g")["v"].transform("mean")# broadcast to original shapedf.groupby("g").filter(lambdax:len(x)>100)df.pivot_table(index="r",# keys to group pivot table index. becomes rows. each value will become a row in the new table.columns="c",# keys to become the new columns of the table.values="v",# data that gets aggregatedaggfunc="sum",# how to aggregate functions. function / list of functions e.g. ["sum", "mean"]fill_value=0)df.melt(id_vars="id",value_vars=["a","b"])df["col"].value_counts()pd.crosstab(df.r,df.c,margins=True)df.groupby("g")["v"].quantile([0.1,0.5,0.9])
pd.merge(left,right,on="key",how="inner"|"left"|"right"|"outer")pd.merge(left,right,left_on="a",right_on="b")pd.concat([df1,df2],axis=0)# verticalpd.concat([df1,df2],axis=1)# horizontalleft.join(right,on="key")# join on index/columnpd.merge_asof(left,right,on="timestamp",direction="backward")# most recent <= timestamp# merge_asof requires both sorted by the merge key# duplicate keys cause row explosion (m:n)
# Vectorize — avoid iterrows/applydf["notional"]=df["price"]*df["size"]# fastdf.apply(lambdar:r.price*r.size,axis=1)# slowfor_,rindf.iterrows():...# slowest[r.price*r.sizeforrindf.itertuples()]# faster than iterrows# eval / query for large DataFramesdf.query("a > 0.5 and b < 0.3")# avoid evaluating using Python. much faster.mask=df.eval("a > 0.5 and b < 0.3")# Categorical for low-cardinality stringsdf["symbol"]=df["symbol"].astype("category")# Downcast numericsdf["size"]=pd.to_numeric(df["size"],downcast="integer")df["price"]=pd.to_numeric(df["price"],downcast="float")# Memorydf.memory_usage(deep=True).sum()# # Chunked processingforchunkinpd.read_csv("big.csv",chunksize=10000):process(chunk)# cumsum is vectorized — prefer over loopsdf["cum_vwap"]=(df.price*df.size).cumsum()/df.size.cumsum()