利用python进行数据分析(书籍)

数据聚合与分组运算

df = pd.DataFrame({'key':['a','b','a','a'],'data':np.random.randint(1,10,4)})
df

# groupby的本质
groupd = df['data'].groupby(df['key'])
groupd
# Groupby技术,另一个术语解释就是 split-apply-combine
# 第一阶段 根据你所提供的一个或多个键被拆分为多组
# 第二阶段 将一个函数应用到各个分组上,并产生以个新值
# 第三阶段 所有这些函数的执行结果被合并到最终的结果对象中
# groupd 是GroupBy对象。它实际上还没有进行任何计算,只是含有一些有关分组键df['key']的中间数据而已。换句话说,该对象
# 已经有了接下来对各分组执行运算所需的一切信息。
# 这里最重要的是,数据根据分组键进行聚合,产生了一个新的Series,其索引为key列中的惟一值。


# groupby 的语法糖
# 对于由DataFrame产生的GroupBy对象,如果用一个或一组列名对其进行索引,就能实现选取部分列
# 进行聚合的目的。
df.groupby(df['key1'])['data1']
# 是以下代码的语法糖
df['data1'].groupby(df['key1'])


# groupby + 函数
# 相对于字典或Series,python函数在定义分组映射关系时可以更有创意且更为抽象。
# 任何被当做分组键的函数都会在各个索引值上被调用一次,其返回值就会被当做分组名称。
# 假如你希望根据人名的长度进行分组,虽然可以求取人格字符串长度数组,但其实仅仅
# 传入一个len函数就可以了。高,实在是高。
people.groupby(len).sum()



# 数据聚合
# 对于聚合,我指的是任何能够从数组中产生标量值的数据转换过程,比如,max(),min()。
# 然而,并不是只能是使用这些方法,你可以使用自己发明的聚合运算,还可以调用分组对象
# 上已经定义好的任何方法。例如,quantile()

# 虽然quantile没有明确的实现与groupby对象,但它是一个series方法,所以这里是能用的。
# 实际上,GroupBy会高效的对Series进行切片,然后对各片调用piece,quantile,最终将这些结果
# 组装成最终结果。

df['data1'].group(df['key1']).quantile(0.9)

# 如果使用自己的聚合函数,只需将其传入agg方法或aggregate方法
f['data1'].group(df['key1']).agg(peak_to_peak)




# 分组级运算和转换
# 聚合只不过是分组运算的其中一种而已,它是数据转换的一个特例,也就是说,它接受
# 能够将一维数组简化为标量值的函数。
# 而transform和apply方法,它们能够执行更多其它的分组运算。

# 跟aggregate一样,transform也是一个有这严格条件的特殊函数:传入的函数只能产生两种结果:
# 要么产生一个可以广播的标量值,如np.mean,要么产生一个相同大小的结果数组。
# 最一般化的GroupBy方法是apply。
# apply会将待处理的对象拆分成多个片段,然后对各片段调用传入的函数,最后尝试将各
# 片段组合到一起。


def top(df,n=5,column='tip_pct'):
    return df.sort_index(by=column)[-n:]

tips.groupby('smoker').apply(top,n=6,column='total_pill')


# 这里发生了什么?
# top函数在DataFrame的各个片段上调用,然后由pandas.concat连接在一起,并以分组名称进行了标记。
# 于是最终结果就有了一个层次化索引。
# 如果传给apply的函数能够接受其它参数或关键字,则可以将这些内容放在函数名后面一并传入。

# 除了这些基本用法之外,能否充分发挥apply的威力很大程度上取决于你的创造力。传入的
# 那个函数能够做什么全由你说了算,它只需要返回一个pandas对象或标量值即可。



# 透视表和交叉表
# 透视表是一种常见的数据汇总工具。它根据一个或多个键对数据进行聚合,并根据行和列上的分组键
# 将数据分配到各个矩形区域中。在python和pandas中。可以通过groupby功能重塑运算制造透视表。
# DataFrame有一个pivot_table方法,可以实现透视功能。
# 应用场景还是很广的。
tips.pivot_table(values,rows=,cols=,aggfunc=,fill_value=,margins=)

# 交叉表 crosstab
# 交叉表是一种用于计算分组频率的特殊透视表。功能就很单一了,只是将某个矩形区域内计数。
pd.crosstab([tips.time,tips.day],tips.smoker,margins=True)

# [tips.time,tips.day] 相当于 rows
# tips.smoker 相当于 cols

猜你喜欢

转载自www.cnblogs.com/654321cc/p/12354075.html