分组级运算和转换

假设要添加一列的各索引分组平均值

第一种方法
import pandas as pd
from pandas import Series
import numpy as np

df = pd.DataFrame([[-2.04708,1.393406,'a','one'],
              [0.478943,0.092908,'a','two'],
              [-0.519439,0.281746,'b','one'],
              [-0.555730,0.769023,'b','two'],
              [1.965781,1.246435,'a','one'],
             ], columns=['data1','data2','key1','key2'])
df

        data1     data2    key1 key2
0   -2.047080   1.393406    a   one
1   0.478943    0.092908    a   two
2   -0.519439   0.281746    b   one
3   -0.555730   0.769023    b   two
4   1.965781    1.246435    a   one

# 先聚合求出平均值
key1_means = df.groupby('key1').mean().add_prefix('mean_')
key1_means

       mean_data1  mean_data2
key1
a      0.132548   0.910916
b     -0.537584   0.525385

# 在通过聚合函数加到DataFrame
pd.merge(df, key1_means,left_on='key1', right_index=True)

       data1      data2   key1  key2    mean_data1  mean_data2
0   -2.047080   1.393406    a   one      0.132548   0.910916
1   0.478943    0.092908    a   two      0.132548   0.910916
4   1.965781    1.246435    a   one      0.132548   0.910916
2   -0.519439   0.281746    b   one     -0.537584   0.525385
3   -0.555730   0.769023    b   two     -0.537584   0.525385
第二种方法 transform,会将一个函数应用到各个分组,有严格条件,要么传入可以广播的标量,要么产生一个相同大小的结果数组
df_mean = df.groupby('key2').transform(np.mean).add_prefix('mean_')
df_mean

    mean_data1  mean_data2
0   -0.200246   0.973862
1   -0.038393   0.430966
2   -0.200246   0.973862
3   -0.038393   0.430966
4   -0.200246   0.973862

pd.concat([df,df_mean],axis=1)

      data1       data2   key1  key2  data1      data2
0   -2.047080   1.393406    a   one -0.200246   0.973862
1   0.478943    0.092908    a   two -0.038393   0.430966
2   -0.519439   0.281746    b   one -0.200246   0.973862
3   -0.555730   0.769023    b   two -0.038393   0.430966
4   1.965781    1.246435    a   one -0.200246   0.973862

apply一般性的'拆分-应用-合并'

apply会将待处理的对象拆分成多个片段,然后对各片段调用传入的函数,最后尝试将各片段组合到一起

# 选取指定列具有最大值的行的函数
def top(df, n=3, column='tip_pct'):
    return df.sort_index(by=column)[-n:]

tips = pd.read_csv('C:/Users/1/Desktop/tips.csv')
tips['tip_pct'] = tips['tip']/tips['total_bill']
tips.head()

 total_bill tip       sex   smoker  day  time   size    tip_pct
0   16.99    1.01   Female   No     Sun Dinner  2      0.059447
1   10.34    1.66   Male     No     Sun Dinner  3      0.160542
2   21.01    3.50   Male     No     Sun Dinner  3      0.166587
3   23.68    3.31   Male     No     Sun Dinner  2      0.139780
4   24.59    3.61   Female   No     Sun Dinner  4      0.146808

# 选取前三个最大值
top(tips,n=3)

total_bill  tip      sex    smoker  day time    size    tip_pct
67  3.07    1.00    Female  Yes     Sat Dinner   1     0.325733
178 9.60    4.00    Female  Yes     Sun Dinner   2     0.416667
172 7.25    5.15    Male    Yes     Sun Dinner   2     0.710345

# 按是否吸烟分组,选前三个最大的值
# 过程是top函数在各个片段上调用后,结果由pandas.concat组装到一起
tips.groupby('smoker').apply(top)

             total_bill tip      sex  smoker  day   time    size     tip_pct
smoker
No     51       10.29   2.60    Female  No    Sun   Dinner   2       0.252672
       149      7.51    2.00    Male    No    Thur  Lunch    2       0.266312
       232      11.61   3.39    Male    No    Sat   Dinner   2       0.291990
Yes    67       3.07    1.00    Female  Yes   Sat   Dinner   1       0.325733
       178      9.60    4.00    Female  Yes   Sun   Dinner   2       0.416667
       172      7.25    5.15    Male    Yes   Sun   Dinner   2       0.710345

# 如果传给apply的函数能够接受其他参数或关键字,则可以将这些一并传入
# 总花费的钱,按是否吸烟和每周的天数来找出每天其中价格最高的,n代表返回的数据前几个
tips.groupby(['smoker','day']).apply(top, n=1, column='total_bill')

              total_bill    tip      sex    smoker     day  time    size    tip_pct
smoker day
No     Fri  94  22.75       3.25    Female  No         Fri  Dinner   2      0.142857
       Sat  212 48.33       9.00    Male    No         Sat  Dinner   4      0.186220
       Sun  156 48.17       5.00    Male    No         Sun  Dinner   6      0.103799
       Thur 142 41.19       5.00    Male    No         Thur Lunch    5      0.121389
Yes    Fri  95  40.17       4.73    Male    Yes        Fri  Dinner   4      0.117750
       Sat  170 50.81      10.00    Male    Yes        Sat  Dinner   3      0.196812
       Sun  182 45.35       3.50    Male    Yes        Sun  Dinner   3      0.077178
       Thur 197 43.11       5.00    Female  Yes        Thur Lunch    4      0.115982

# 分组调用describe的方法
tips.groupby('smoker')['tip_pct'].describe().T

smoker     No          Yes
count   151.000000  93.000000
mean    0.159328    0.163196
std     0.039910    0.085119
min     0.056797    0.035638
25%     0.136906    0.106771
50%     0.155625    0.153846
75%     0.185014    0.195059
max     0.291990    0.710345

# 本质是,下面两行代码的快捷键而已
f = lambda x:x.describe()
tips.groupby('smoker')['tip_pct'].apply(f).unstack('smoker')

smoker      No        Yes
count   151.000000  93.000000
mean    0.159328    0.163196
std     0.039910    0.085119
min     0.056797    0.035638
25%     0.136906    0.106771
50%     0.155625    0.153846
75%     0.185014    0.195059
max     0.291990    0.710345

# 禁用层次化索引
tips.groupby('smoker',group_keys=False).apply(top)

    total_bill  tip      sex    smoker  day     time      size   tip_pct
51     10.29    2.60    Female    No    Sun    Dinner      2    0.252672
149     7.51    2.00    Male      No    Thur   Lunch       2    0.266312
232    11.61    3.39    Male      No    Sat    Dinner      2    0.291990
67     3.07     1.00    Female    Yes   Sat    Dinner      1    0.325733
178    9.60     4.00    Female    Yes   Sun    Dinner      2    0.416667
172    7.25     5.15    Male      Yes   Sun    Dinner      2    0.710345

分位数和桶分析


frame = pd.DataFrame({'data1':np.random.randn(1000),
                      'data2':np.random.randn(1000)})
factor = pd.cut(frame['data1'],4)
factor[:5]

0    (-1.573, 0.112]
1    (-1.573, 0.112]
2    (-1.573, 0.112]
3    (-1.573, 0.112]
4    (-1.573, 0.112]
Name: data1, dtype: category
Categories (4, interval[float64]): [(-3.264, -1.573] < (-1.573, 0.112] < (0.112, 1.797] < (1.797, 3.482]]

def get_stats(group):
    return {'min':group.min(),'max':group.max(),'count':group.count(),'mean':group.mean()}

# 长度即每个区间相等的桶(区间大小相等)
frame.data2.groupby(factor).apply(get_stats).unstack()

                 count    max         mean          min
data1
(-3.264, -1.573]  57.0  3.236024    0.100749    -2.149984
(-1.573, 0.112]   484.0 2.843239    -0.058549   -3.606913
(0.112, 1.797]    425.0 2.614935    0.065693    -3.463799
(1.797, 3.482]    34.0  1.791511    -0.049641   -1.756306

# 大小相等的桶,labels关闭区间名称(数据点数量相等)
ppp = pd.qcut(frame['data1'],4,labels=False)
frame.data2.groupby(ppp).apply(get_stats).unstack()

    count      max        mean         min
data1
0   250.0   3.236024    -0.032592   -2.750112
1   250.0   2.843239    -0.068005   -3.606913
2   250.0   2.614935    0.103220    -2.380858
3   250.0   2.612170    0.011922    -3.463799

Pandas分组级运算和转换的更多相关文章

  1. Pandas分组运算(groupby)修炼

    Pandas分组运算(groupby)修炼 Pandas的groupby()功能很强大,用好了可以方便的解决很多问题,在数据处理以及日常工作中经常能施展拳脚. 今天,我们一起来领略下groupby() ...

  2. pandas分组和聚合

    Pandas分组与聚合 分组 (groupby) 对数据集进行分组,然后对每组进行统计分析 SQL能够对数据进行过滤,分组聚合 pandas能利用groupby进行更加复杂的分组运算 分组运算过程:s ...

  3. Python Pandas分组聚合

    Pycharm 鼠标移动到函数上,CTRL+Q可以快速查看文档,CTR+P可以看基本的参数. apply(),applymap()和map() apply()和applymap()是DataFrame ...

  4. Pandas分组

    GroupBy技术 分组运算的过程可以用下面的流程图表示出来 import pandas as pd from pandas import Series import numpy as np df = ...

  5. pandas分组group

    Pandas对象可以分成任何对象.有多种方式来拆分对象,如 - obj.groupby(‘key’) obj.groupby([‘key1’,’key2’]) obj.groupby(key,axis ...

  6. Pandas分组(GroupBy)

    任何分组(groupby)操作都涉及原始对象的以下操作之一.它们是 - 分割对象 应用一个函数 结合的结果 在许多情况下,我们将数据分成多个集合,并在每个子集上应用一些函数.在应用函数中,可以执行以下 ...

  7. LINQ 101——分组、Set、转换、Element

    一.Grouping(分组) 例1:对于0-9数按被3整除的结果分组 代码: static void Linq1() { , , , , , , , , , }; var numModBy3 = fr ...

  8. Pandas分组统计函数:groupby、pivot_table及crosstab

    利用python的pandas库进行数据分组分析十分便捷,其中应用最多的方法包括:groupby.pivot_table及crosstab,以下分别进行介绍. 0.样例数据 df = DataFram ...

  9. HTML中的行级标签和块级标签 《转换》

    1.html中的块级标签 显示为“块”状,浏览器会在其前后显示折行.常用的块级元素包括: <p>, <ul>,<table>,<h1~h6>等. 2.h ...

随机推荐

  1. 自定义框架(MyMvc)

    //初次接触自定义框架,简单的登录功能的实现流程:: 当我们实现登录功能的时候,首先会创建一个login.jsp 会写这些登录表单 <form action="loginAction. ...

  2. HDU 4310 Hero (贪心算法)

    A - Hero Time Limit:3000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Sta ...

  3. 二模 (12) day1

    第一题: 题目大意: 求由N个1,M个0组成的排列的个数,要求在排列的任意一个前缀中,1的个数不少于0的个数.N,M<=5000. 解题过程: 1.看到N,M的范围就明确肯定不会是dp,因为起码 ...

  4. git deployment strategy

    http://nicolasgallagher.com/simple-git-deployment-strategy-for-static-sites/ You can still ignore a ...

  5. 乳草的入侵//BFS

    P1030 乳草的入侵 时间: 1000ms / 空间: 131072KiB / Java类名: Main 背景 USACO OCT09 6TH 描述 Farmer John一直努力让他的草地充满鲜美 ...

  6. 何给域名配置https证书

    原文链接:https://www.cnblogs.com/ymwang/p/6893105.html http和https的区别就是,后者在网络传输过程中会很安全,原因就是给http安装了SSL证书. ...

  7. 推荐一本写给IT项目经理的好书

    原文地址:http://www.cnblogs.com/cbook/archive/2011/01/19/1939060.html (防止原文作者删除.只能拷贝一份了) 推荐一本写给IT项目经理的好书 ...

  8. Java_IO异常处理方式_入门小笔记

    package IO; import java.io.FileWriter; import java.io.IOException; /** * IO异常处理方式 */ class FileWrite ...

  9. Sql Server数据库资料收集

    1.表分区 http://www.cnblogs.com/huangxincheng/p/3565755.html 2.MVP教程地址:http://www.cnblogs.com/lyhabc/p/ ...

  10. android开发学习---基础知识学习、如何导入已有项目和开发一个电话拨号器

    一.基础知识点学习  1.Android体系结构 如图所示,android 架构分为三层: (1)最底层是linux内核,主要是各种硬件的驱动,如相机驱动(Camera Driver),闪存驱动(Fl ...