zoukankan      html  css  js  c++  java
  • pandas取组内最大值行

    使用SQL的取法在随笔https://www.cnblogs.com/kang-mei-208/p/13845529.html中有提及

    这里介绍pandas的取法

    本文是实验楼课程数据分析与挖掘的练习题。友情推荐。

    1.数据输入输出

    数据输入用的是美国地震观测数据。
    http://labfile.oss.aliyuncs.com/courses/1176/earthquake.csv

    读入数据样例如下:

    time latitude longitude depth mag magType nst gap dmin rms net id updated place type horizontalError depthError magError magNst status locationSource magSource
    2018-09-19T02:42:05.360Z 38.7765 -122.729 1.47 0.72 md 6 150 0.008868 0.02 nc nc73087016 2018-09-19T02:43:41.278Z 2km E of The Geysers, CA earthquake 0.67 0.61 0.14 2 automatic nc nc
    2018-09-19T02:31:38.744Z 66.385 -157.328 5.5 1.3 ml 0.83 ak ak20258344 2018-09-19T02:36:28.347Z 61km SSW of Kobuk, Alaska earthquake 0.3 automatic ak ak
    2018-09-19T02:29:39.802Z 62.3758 -149.731 0 1.6 ml 0.72 ak ak20258342 2018-09-19T02:36:28.112Z 20km ENE of Talkeetna, Alaska earthquake 0.4 automatic ak ak
    2018-09-19T02:23:47.301Z 60.4384 -143.057 10.6 1 ml 0.28 ak ak20258340 2018-09-19T02:29:26.304Z 54km NW of Cape Yakataga, Alaska earthquake 0.3 automatic ak ak
    2018-09-19T02:16:19.050Z 37.2318 -114.941 7.9 0.7 ml 12 263.1 0.181 0.25 nn nn00657223 2018-09-19T02:17:34.122Z 24km SE of Alamo, Nevada earthquake 22.4 automatic nn nn
    2018-09-19T02:08:05.660Z 33.65283 -116.734 14.28 1.17 ml 41 58 0.06049 0.15 ci ci37359938 2018-09-19T02:18:38.670Z 10km S of Idyllwild, CA earthquake 0.19 0.3 0.176 26 automatic ci ci

    要求输出格式如下:

    mag region times
    micro NV 353
    light Nevada 150
    strong CA 31
    major Japan 2
    great Indonesia 1

    其处理过程为:

    1. place字段的最后一个逗号后的地区构成region字段
    2. 将mag按以下规则映射:
    震级 描述
    [0, 2) micro
    [2, 5) light
    [5, 7) strong
    [7, 9) major
    >=9 great
    1. 按照震级、地区聚合,算出各地区下各震级的发生次数
    2. 取出各个震级地震次数最多的地区

    2.代码

    # -*- coding: utf-8 -*-
    """
    Created on Sun Jan 31 23:50:24 2021
    
    @author: 25469
    """
    
    import pandas as pd
    
    
    def clean():
    
        ### 补充代码 ###
    
        df_clean = None
        df=pd.read_csv('earthquake.csv')
    
        df1=pd.DataFrame({'time':df.time,'latitude':df.latitude,'longitude':df.longitude,'depth':df.depth,'mag':df.mag,'region':df.place.apply(lambda x:x.split(',')[-1])})
    
        df1=df1.dropna().drop_duplicates()
        
        df_clean=df1
    
        return df_clean # 返回最终得到的 DataFrame
    
    
    df=clean()
    
    #映射
    df['mag']=pd.cut(df.mag,bins=[0,2,5,7,9,20],labels=['micro','light','strong','major','great'])
    
    #取出关键字段,聚合计数
    df1=pd.DataFrame({'mag':df.mag,'region':df.region})
    df1['times']=df1.groupby('region').transform('count') #构建聚合计数结果的times字段
    df1.drop_duplicates(inplace=True) #这个聚合和SQL的还是有很大不同,类似开窗函数,需要手动删除重复项
    
    #####得到各震级下最多次数的那行
    #方法一
    
    df_clean=df1.groupby('mag',as_index=False).apply(lambda x:x.sort_values(by='times').iloc[-1:]).reset_index(drop=True)
    
    #方法二
    df_clean=df1.sort_values(by='times',ascending=False).drop_duplicates('mag')
    
    

    这里有两种方法:

    • 用apply方法,将各个group排序后取出最后那行。
    • 依照times排逆序,再以mag字段去重

    这里推荐第一种方法。第二种方法有写些取巧,如果要取第二大的数字就不行了。

    值得一提的是:
    第一种方法的iloc[-1:]这里,我如果只写iloc[-1],不加冒号,会报index错误

    IndexError: single positional indexer is out-of-bounds
    

    而加上冒号后却可以正常输出。他们的意思相同,都是取dataframe最后一行。

    这种方法我参照的https://zhuanlan.zhihu.com/p/101284491?utm_source=wechat_session文章
    奇怪的是,我输入文章中的数据集时,使用iloc[-1]却不报错。

    最终我也没能搞明白我的数据集最后一步iloc[-1]为什么报错,好在加上冒号能够解决。

    为了节省时间,我就不贴出来每一步操作结果的输出样例了,读者可以自行逐句看看输出,理解一下各个方法的输出。

  • 相关阅读:
    MyBatis 缓存机制
    MyBatis 动态SQL
    SpringMVC的简介与使用
    捕获组和前后查找
    正则表达式:( ) 小括号、[ ] 中括号、{ } 大括号的区别
    343.整数拆分
    74. 搜索二维矩阵
    数的划分
    213.打家劫舍||
    整数划分为k份
  • 原文地址:https://www.cnblogs.com/kang-mei-208/p/14357695.html
Copyright © 2011-2022 走看看