利用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

时间序列

# 时间序列
# Pandas提供了一组标准的时间序列处理工具和数据算法。你可以高效的进行切片/切块,
# 聚合,对定期/不定期的时间序列进行重采样等。这些工具大部分对金融和经济数据尤为有用,
# 当然也可以用它们来分析服务器日志数据。


# 日期的范围,频率以及移动
# pandas中的时间序列一般被认为是不规则的,也就是说,它们没有固定的频率。但是,它常常需要以
# 某种相对固定的频率进行分析,比如每日,每月,每15分钟。这个时候只需调用resample即可。





# 重采样及频率转换
# 重采样指的是将时间序列从一个频率转换到另一个频率的处理过程。将高频率数据聚合到低频率
# 称为降采样,将低频率数据转换到高配率则称为升采样。并不是所有的重采样都能被划分到这两个
# 大类中。例如,将W-WED转换为W-FRI既不是升采样也不是降采样。

# Pandas对象都有一个resample方法,它是各种频率转换工作的主力函数。

# 降采样
# 方法一 resample
# ts.resample('D',how='sum')
# 将数据聚合到规整的低频率是一件非常普通的时间序列处理任务。待聚合的数据不必拥有固定的
# 频率,期望的频率很自动定义聚合的面元边界。
# 在用resample对数据进行降采样时,需要考虑两样东西
    # 个区间哪边是闭合的, 默认 colsed='right'
    # 如何标记各个聚合面元,用区间的开头还是末尾 默认 label='right'
    # 用于产出聚合值的函数名,默认为 mean.
    
# 方法二  groupby
# 只需要传入一个能够访问时间序列的索引上的这些字段的函数即可。
# ts.groupby(lambda x:x.month).mean()
# ts.groupby(lambda x:x.weekday).mean()






# 移动窗口函数
# 在移动窗口(可以带有指数衰减权数)上计算的各种统计函数也是一类常见于时间序列的数组变换。
# 我将它们称为移动窗口函数,其中还包括那些窗口不定长的函数,如指数加权移动平均。跟其它
# 统计函数一样,移动窗口函数也会自动排除缺失值。

# 典型应用场景:股价

Series.rolling(10).mean()/count()/std()/sum()/corr()

金融和经济数据应用

# 数据规整化方面的话题
# 时间序列以及截面对其
#     pandas可以在算术运算中自动对其数据,并在sum这样的函数中排除缺失数据(np.nan)。
    
# 频率不同的时间序列的运算
# 经济学时间序列常常有这按年,月,日计算的或其它更特殊的频率,有些完全四不规则的。
# 比如说,盈利预测调整随时都有可能发生。
# 频率转换和重对其的两大主要工具是resample和reindex。resample用于将数据转换到固定频率,
# 而reindex则用于是数据符合一个新的索引。它们都支持插值(如向前填充)逻辑。
# reindex 和 resample一块记

df1 = pd.DataFrame(np.random.randint(1,20,10),index=pd.date_range('2010-01-01',periods=10),columns=['A'])
df2 = pd.DataFrame(np.random.randint(21,40,10),index=pd.date_range('2010-01-05',periods=10),columns=['A'])
df1.reindex(df2.index,method='bfill')


# 拼接多个数据源
# 在一个特定的时间点上,从一个数据源切到另一个数据源
# 用另一个时间序列对当前时间序列中的缺失值打补丁
# 将数据中的符号(国家,资产代码等)替换为实际数据。

# 第一种情况 pd.concat()
# 第二种情况 df1.combine_first(df2) /df1.update(df2,overwrite=False)
原文地址:https://www.cnblogs.com/654321cc/p/12354075.html