精华内容
下载资源
问答
  • pandas删除某列为空的行
    2021-08-21 11:26:23

    index 行索引
    columns 列索引

    concat

    concat函数是在pandas底下的方法,可以将数据根据不同的轴作简单的融合

    pd.concat(objs, axis=0, join='outer', join_axes=None, ignore_index=False,
        keys=None, levels=None, names=None, verify_integrity=False)
    

    参数说明
    objs: series,dataframe或者是panel构成的序列lsit
    axis: 需要合并链接的轴,0是行1是列
    join:连接的方式 inner 交集,或者outer 并集

    来源:https://www.jb51.net/article/164905.htm

    • 例子
    result = pd.concat([df1, df4], axis=1)
    

    在这里插入图片描述

    loc

    https://blog.csdn.net/liu_liuqiu/article/details/99338267
    在这里插入图片描述
    loc[行,列] 先行后列,以逗号分割 前闭后闭

    
    data.loc[:,"Age"]
    
    行分片  [:] 表示全部行
    "Age" 表示Age列
    

    在这里插入图片描述

    append

    https://blog.csdn.net/sinat_29957455/article/details/84961936

    在这里插入图片描述

    数据读取

    在这里插入图片描述

    mysql

    import pymysql
    conn = pymysql.connect(
            host='127.0.0.1',
            user='root',
            password='123456',
            database='authority',
            charset='utf8'
        )
    
    mysql_page = pd.read_sql("select * from user", con=conn)
    
    print(mysql_page)
    

    read_excel()

    https://blog.csdn.net/muyashui/article/details/111053591

    官方API:https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_excel.html#pandas.read_excel

    """
    # =============================================================================
    # 3.1 Python工具包
    # =============================================================================
    1 Python中与数据处理相关的部分工具包
        - numpy:基础数据计算工具包
        - pandas:数据处理,python数据处理中最重要的工具包
        - matplotlib:静态可视
        - seaborn:静态可视
        - pyechart:动态可视,需要手动安装工具包
    
    2 工具包的使用  ★★★★★
        - 步骤:导入工具包;调用工具包中的方法或属性
            - import padas as pd  # 导入工具包并简写成pd,写成其他名称也可以,写作“pd”只是大家的习惯。
            - pd.read_excel()
        
    3 工具包中方法与excel中函数类比 ★★★★★
        - =VLOOKUP(F11,A1:D20,2,0)    # excel函数用等号开始,vlookup有4个参数
    
        - pandas.read_excel(io, sheet_name=0, header=0, **kwds) # pythong中函数用"."
    
    # =============================================================================
    # 3.2 读取excel文件  : pandas.read_excel()
    # =============================================================================
    
    pandas.read_excel(io, sheet_name=0, header=0, names=None, index_col=None, usecols=None, 
                      squeeze=False, dtype=None, engine=None, converters=None, true_values=None, 
                      false_values=None, skiprows=None, nrows=None, na_values=None, keep_default_na=True, 
                      verbose=False, parse_dates=False, date_parser=None, thousands=None, comment=None, 
                      skip_footer=0, skipfooter=0, convert_float=True, mangle_dupe_cols=True, **kwds)
        - 常用参数:
            - io:excel的路径,选中文件,鼠标右键,在"属性"中找到文件位置,再补充上文件名称,则为完整路径。注意反斜杠方向   ★★★★★ 
            - sheet_name:工作表的名称。当不输入时,默认读取第一个工作表
        - 不常用参数:
            - index_col :指定某一列为索引。index_col=1
            - names :列名称,传入list数据
            - header:指定行作为列名,默认为第1行。header=[1,2]多级索引
            - usecols:读取指定列。usecols = ["A","B"]
    """
    
    
    # =============================================================================
    # 3.2.1 常用参数io:excel文件所在的路径
    # =============================================================================
    # 导入pandas工具包
    import pandas as pd
    
    # 方式1 ★★★
    data1 = pd.read_excel('D:/python/课件/data/泰坦尼克数据.xlsx')
    
    # 方式2 ★★★
    # 导入os工具包
    import os
    # 设置默认路径,当读取此文件夹下的文件时,直接输入文件名称就可以
    os.chdir('D:/python/课件/data/')
    data2 = pd.read_excel('泰坦尼克数据.xlsx')
    
    # =============================================================================
    # 3.2.2 常用参数sheet_name:读取的工作表的名称
    # =============================================================================
    # 方式1 ★★★
    data3 = pd.read_excel('泰坦尼克数据.xlsx',sheet_name='Sheet1')
    # 方式2
    data4 = pd.read_excel('泰坦尼克数据.xlsx',sheet_name=1)
    
    # =============================================================================
    # 3.2.3 常用参数index_col:设置某一列为索引。一般在数据中有序列编号列时使用
    # =============================================================================
    data5 = pd.read_excel('泰坦尼克数据.xlsx',index_col='乘客ID')
    # 设置所以一般用DataFrame中set_index()方法 ★★★
    
    # =============================================================================
    # 3.2.4 常用参数names:更改列名称。列名长度需要与数据列名数量一致,否则会报错
    # =============================================================================
    data6 = pd.read_excel('泰坦尼克数据.xlsx',names=['变量1','变量2','变量3','变量4','变量5','变量6','变量7','变量8','变量9','变量10','变量11','变量12'])
    
    # 更改列名一般用DataFrame中columns属性★★★
    data6.columns = ['乘客ID', '是否存活', '票类', '姓名', '性别', '年龄', '乘客兄弟姐妹个数',
                     '乘客父母/孩子的个数', '票号','票价', '仓位', '登船港口']
    
    # =============================================================================
    # 3.2.5 常用参数usecols:读取指定列
    # =============================================================================
    data7 = pd.read_excel('泰坦尼克数据.xlsx',usecols=['姓名','性别','年龄'])
    
    # 方式二★★★
    data8 = pd.read_excel('泰坦尼克数据.xlsx')[['姓名','性别','年龄']]  # 注意是两个中括号
    
    # =============================================================================
    # 3.2.5 常用参数header:列名所在位置
    # =============================================================================
    data9 = pd.read_excel('泰坦尼克数据.xlsx',header=1) # 把第二行作为表头
    data10 = pd.read_excel('泰坦尼克数据.xlsx',header=None)
    
    

    read_csv()

    https://blog.csdn.net/muyashui/article/details/111053765

    """
    # =============================================================================
    # 3.2 读取csv txt文件  : pandas.read_csv()
    # =============================================================================
    
    pandas.read_csv(filepath_or_buffer: Union[str, pathlib.Path, IO[~AnyStr]], sep=',', delimiter=None, 
                    header='infer', names=None, index_col=None, usecols=None, squeeze=False, prefix=None, 
                    mangle_dupe_cols=True, dtype=None, engine=None, converters=None, true_values=None, 
                    false_values=None, skipinitialspace=False, skiprows=None, skipfooter=0, nrows=None, 
                    na_values=None, keep_default_na=True, na_filter=True, verbose=False, skip_blank_lines=True, 
                    parse_dates=False, infer_datetime_format=False, keep_date_col=False, date_parser=None, 
                    dayfirst=False, cache_dates=True, iterator=False, chunksize=None, compression='infer', 
                    thousands=None, decimal=b'.', lineterminator=None, quotechar='"', quoting=0, doublequote=True, 
                    escapechar=None, comment=None, encoding=None, dialect=None, error_bad_lines=True,
                    warn_bad_lines=True, delim_whitespace=False, low_memory=True, memory_map=False, 
                    float_precision=None)
    
    **常用参数:**
        - filepath_or_buffer :文件路径 ,和读取excel中io参数一样
        - sep :分隔符,默认逗号
        - encoding :一般utf-8 或者 gbk                                                                       
    """
    # 导入pandas工具包,并简写为pd
    import pandas as pd
    
    # =============================================================================
    # # 读取csv数据
    # =============================================================================
    data1 = pd.read_csv('D:/python/课件/data/titanic_train.csv')
    
    # =============================================================================
    # # 读取txt数据
    # =============================================================================
    data2 = pd.read_csv('D:/python/课件/data/zhengqi_train.txt')   # 读取后数据没有按照列分开
    data3 = pd.read_csv('D:/python/课件/data/zhengqi_train.txt',sep='\t')  #其他特殊符号:回车(\r),换行(\n),制表符(\t),空白字符\s 多个空白字符\s+
    
    
    

    查看数据

    # 导入pandas工具包, 并简写为pd
    import pandas as pd 
    # 读取数据
    data1 = pd.read_excel('D:/python/课件/data/泰坦尼克数据.xlsx')
    
    # =============================================================================
    # 1 数据基本信息info: 显示变量名称,数值格式,非缺失值个数等
    # =============================================================================
    data1.info()
    
    
    # =============================================================================
    # 2 前n行,后n行,抽样:数据量很大时建议使用
    # =============================================================================
    temp1 = data1.head(50)  # 默认是前5行
    temp2 = data1.tail(50)  # 默认是后5行
    temp3 = data1.sample(50) # 默认是1行
    
    
    # # =============================================================================
    # # 3 列名:经常使用,比如写代码时不能准确记住变量名称,可用此方法获取
    # # =============================================================================
    data1.columns   # 复数,没有括号
    
    
    # # =============================================================================
    # # 4 描述性统计:默认计算数值变量的均值、标准差、最大值、最小值、分位数
    # # =============================================================================
    temp4 = data1.describe()
    temp5 = data1.describe().round(2)  # 保留两位小数
    temp6 = data1.describe().round(2).T  # 行列转置
    
    # # =============================================================================
    # # 5 缺失值个数(值为空):经常使用
    # # =============================================================================
    data1.isna().sum()   
    data1['仓位'].isnull().value_counts()
    
    # # =============================================================================
    # # 6不重复项:经常使用
    # # =============================================================================
    data1['登船港口'].unique()
    
    
    # # =============================================================================
    # # 7计数:计算分类变量个数
    # # =============================================================================
    data1['性别'].value_counts()
    
    

    合并数据

    # 导入工具包并简写为pd
    import pandas as pd
    # 导入os工具包
    import os
    # 设置读取文件的默认路径  下面所有路径的绝对路径从此开始
    os.chdir('D:/python/课件/data/数据合并/')
    
    
    # =============================================================================
    # 批量读取数据
    # =============================================================================
    
    # 获取文件夹相关信息,os.walk()方法返回3个结果,其中files是文件名列表。
    # root, dirs, files只是自定义的变量名称,可写成别的名
    for root, dirs, files in os.walk('.'):
        print(files)  
     
    # 定义一个空的dataframe,读取的每个表中的数据都添加到此变量中
    data = pd.DataFrame()  
    
    # 遍历所有文件
    for i in files:  # 依次读取files列表中的文件名
        # 读取第i个文件,"."为上面设置的默认路径,i为文件名称。组合在一起正好为文件路径
        datai = pd.read_csv('./' + i)   
        # 计算文件行数
        datai_len = len(datai)
        # 读取的文件添加到data变量中
        data = data.append(datai)   # 添加到总的数据中
        # print中格式化写法。%i表示此处为一整数,整数的值为引号外面%后面的变量,按顺序获取。其他写法 %s:字符串  %f:小数
        print('文件%i列, 读取%i行数据,名称:%s'%(len(datai.columns),datai_len,i)) 
        
    # =============================================================================
    # # 保存为excel到电脑
    # =============================================================================
    data.to_excel('D:/python/课件/data/合并后的数据.xlsx')
    
    

    DataFrame、Series

    '''
    # =============================================================================
    # Numpy中基本数据结构
    # =============================================================================
     - 数组(array)
    
    '''
    # 生成一维数组
    import numpy as np
    arr1 = np.array([1,2,3,4,5])
    arr1
    
    # 生成二维数组
    arr2 = np.array([[1,2,3,4,5],
                     [6,7,8,9,10]])
    arr2
    
    
    # 数组属性
    print(arr2.shape)
    print(arr2.size)
    print(arr2.dtype)
    
    
    # 数组的运算
    arr3 = arr2 + 100
    arr3
    
    '''
    # =============================================================================
    # Pandas中基本数据结构
    # =============================================================================
     - DataFrame(二维表):类似于excel中的一个表格
     - Series(一维表):类似于excel中的一个表格中一行或者一列
    '''
    
    # =============================================================================
    # 读取数据
    # =============================================================================
    # 导入pandas工具包
    import pandas as pd
    
    data1 = pd.read_excel('D:/python/课件/data/泰坦尼克数据.xlsx')
    # 查看其中一列,也可写成data1.姓名 ,一般不用此种写法
    data2 = data1['姓名']
    # 查看其中一行
    data3 = data1.iloc[100]
    
    
    # =============================================================================
    # 创建数据
    # =============================================================================
    import numpy as np
    #创建一个series,random是np中一个生产随机数的函数
    s1 = pd.Series(np.random.random(5))     # 生成5个 0到1之间的随机数
    
    # 创建一个DataFrame
    data3 = pd.DataFrame(np.random.randint(5,20,(10,5)),  # 生成一个10行5列整数 数组,值在5~20之间
                      columns=list('ABCDE'))
    
    # 数据是几维数据
    data3.shape
    # 获取数据行数,经常在for循环中辅助使用
    data3.shape[0]
    # 数据的索引
    data3.index
    # 数值变量描述性统计
    data3.describe().round(2)
    # 变量的格式
    data3.dtypes
    # 数据的列名
    data3.columns
    # 数据基本信息
    data3.info()
    

    保存为excel

    # 导入pandas工具包,并简写为pd
    import pandas as pd
    # 读取数据
    data1 = pd.read_excel('D:/python/课件/data/泰坦尼克数据.xlsx')
    
    # 简单的数据处理:示例
    # 数据透视表1:按照性别、登录港口统计人数
    result1 = data1.pivot_table('姓名',      # 需要计算统计量的变量(字段)
                                index='性别',   # 行变量,当需要输入多个时 用列表形式 ['','']
                                columns='登船港口', # 列变量,当需要输入多个时 用列表形式 ['','']
                                aggfunc='count', # 需要计算的统计量,'sum','mean','max'等
                                margins=True)   # 是否显示合计
    
    # 数据透视表2:按照性别、票类统计人数
    result2 = data1.pivot_table('姓名',
                                index='性别',
                                columns='票类',
                                aggfunc='count',
                                margins=True)   # 是否显示合计
    
    # result1,result2类型为DataFrame
    ===============================================================================
    # 导出单个excel
    # =============================================================================
    # 常用参数
    #   - 文件路径
    #   - index 是否显示索引
    #   - sheet_name 保存的工作表名称 
    # 最常用写法
    result1.to_excel('D:/python/课件/结果/保存数据1.xlsx')
    # 当索引为数值序列,不期望导出的时候设置index=False
    result2.to_excel('D:/python/课件/结果/保存数据2.xlsx',index=False)
    result2.to_excel('D:/python/课件/结果/保存数据3.xlsx',sheet_name='汇总')
    
    # =============================================================================
    # 多个dataframe数据保存到一个工作簿中
    # =============================================================================
    
    with pd.ExcelWriter('D:/python/课件/结果/保存数据4.xlsx') as writer:
        result1.to_excel(writer,sheet_name='第1个表')
        result2.to_excel(writer,sheet_name='第2个表')
    
    

    数据去重、分列、替换

    import pandas as pd
    data1 = pd.read_csv('D:/python/课件/data/dzdp_data.csv')
    
    '''
    # =============================================================================
    #  数据去重
    # =============================================================================
    '''
    # 查看帮助文档
    help(data1.drop_duplicates)
    
    # =============================================================================
    #  对cus_id 进行去重
    # =============================================================================
    
    # 删除重复的数据,返回一个DataFrame
    data2 = data1.drop_duplicates(subset='cus_id')  # 写成['cus_id']也可以,inplace参数未设置,
    #data1.drop_duplicates(subset='cus_id',inplace=True) 
    # 对某列差看不重复项
    temp1 = data1['cus_id'].unique()
    
    # 判断是否重复
    data1['cus_id'].duplicated()
    
    # =============================================================================
    # 多个字段('kouwei','huanjing','fuwu')去重
    # =============================================================================
    
    data3 = data1.drop_duplicates(subset=['kouwei','huanjing','fuwu'])
    
    
    
    '''
    # =============================================================================
    # 数据分列
    # =============================================================================
    '''
    # =============================================================================
    # 对comment_star字段按照“-”分割
    # =============================================================================
    
    data1['comment_star_re'] = data1['comment_star'].str.split('-')
    
    
    # =============================================================================
    # 对comment_star字段按照“-”分割,取第2个元素
    # =============================================================================
    
    data1['comment_star_re'] = data1['comment_star'].str.split('-',expand=True)[1]
    
    
    '''
    # =============================================================================
    # 数据替换
    # =============================================================================
    '''
    # =============================================================================
    # 按单元格匹配替换
    # =============================================================================
    # 前后都用中括号,成对替换★★★★
    data1['kouwei'].replace(['非常好', '很好', '好', '差', '一般', '无'],
                            [1, 2, 3, 4,5,999],
                            inplace=True)
    
    # 多对一替换★★★★
    data1['huanjing'].replace(['非常好', '很好', '好'],'好',inplace=True)
    
    # 字典格式替换
    data1['fuwu'].replace({'非常好':1, '很好':2,'好':'3','一般':4,'差':5,'无':999},inplace=True)
    
    
    # =============================================================================
    # 按单元格部分替换
    # =============================================================================
    data1['comment_star'] = data1['comment_star'].str.replace('sml','SML')   #部分替换 ,只把sml替换成SML,没有inplace参数
    

    删除行列、更改列名、填充缺失值

    import pandas as pd
    data1 = pd.read_csv('D:/python/课件/data/dzdp_data.csv')
    
    # =============================================================================
    # 删除行列
    # =============================================================================
    # 删除列
    data2 = data1.drop('cus_comment',axis=1) # inplace   ['','']
    
    # 删除行
    data1.drop(4,axis=0,inplace=True)  # axis=0 按行处理
    
    # =============================================================================
    # # 更改列名
    # =============================================================================
    # 1 全部更改:长度需要与表格的列名个数一致
    data1.columns = ['客户id', '评价时间', '星级', '内容', '口味',
           '环境', '服务', '商店id', '评分', '年', '月', '周',
           '小时', '内容长度']
    
    # 2 个别替换,columns= 不能少,还有另一个参数修改索引 index={}
    data1.rename(columns={'客户id':'客户ID','商店id':'商店ID'},inplace=True)
    
    # =============================================================================
    # # 更改列的格式
    # =============================================================================
    data1.info()
    # 改成字符串
    data1['商店ID'] = data1['商店ID'].astype('str')   # 改为整数用int
    # 改为日期格式
    data1['评价时间'] = pd.to_datetime(data1['评价时间'])  
    
    # 保留2位小数
    data1['内容长度/100'] = data1['内容长度'] / 100
    data1['内容长度/100'] = data1['内容长度/100'].round(2)
    
    # map是python一个高级函数,对所有元素进行指定的函数变化;
    # lambda匿名函数,简化了的函数写法
    data1['内容长度/100'] = data1['内容长度/100'].map(lambda x:"%.2f" %x)  
    
    # =============================================================================
    # # 填充缺失值
    # =============================================================================
    # 读取数据
    data2 = pd.read_excel('D:/python/课件/data/泰坦尼克数据.xlsx')
    # 缺失值情况
    data2.isna().sum()
    
    # 按均值填充
    data2['年龄'].fillna(data2['年龄'].mean(),inplace=True)
    
    # 填充为其他值
    data2['仓位'].fillna('无',inplace=True)
    
    # =============================================================================
    # # 删除缺失值
    # =============================================================================
    
    data2.dropna(subset=["登船港口"],inplace=True)  # 此处必须用中括号
    
    
    

    数据透视表df.pivot_table()

    import pandas as pd
    import numpy as np
    import os
    os.chdir('D:/python/课件/data/gaokaodata/')
    
    # =============================================================================
    # 批量读取数据
    # =============================================================================
    # 此数据由和鲸社区整理:https://www.kesci.com/mw/project/5efff5de63975d002c98fc28/dataset
    
    # 获取文件夹相关信息,os.walk()方法返回3个结果,其中files最终要。root, dirs, files只是自定义的变量名称,可写成别的名
    for root, dirs, files in os.walk('.'):
        print(files)  
        
    # 定义一个空的dataframe,读取的每个表中的数据都添加到此变量中   
    data = pd.DataFrame()  
    
    for i in files:  # 依次读取files文件中的元素
        # 读取第i个文件,"."为上面设置的默认路径,i为文件名称。组合在一起正好为文件路径
        datai = pd.read_csv('./' + i)   
        # 计算文件行数
        datai_len = len(datai)
        # 读取的文件添加到data变量中
        data = data.append(datai)   # 添加到总的数据中
        # print中格式化写法。%i表示此处为一整数,整数的值为引号外面%后面的变量,按顺序获取。其他写法 %s:字符串  %f:小数
        print('文件%i列, 读取%i行数据,名称:%s'%(len(datai.columns),datai_len,i)) 
    
    # =============================================================================
    # 数据透视表
    # =============================================================================
    
    '''
    pivot_table(values=None, # 计算的统计量,values可以不用写
                index=None,  # 行变量
                columns=None, # 列字典
                aggfunc='mean', #计算的统计量,可以写成 'sum' 或者 np.sum  两种形式
                fill_value=None, # 缺失值的显示方式
                margins=False, # 是否显示合计行、合计列,False为不显示
                dropna=True,  # 不计算全部为缺失值的列,不常用
                margins_name='All', # 合计行、列的名称,默认为英文单词ALL,可改为"合计","总计"等
                observed=False) # 仅适用于分类索引的,不常用
    '''
    
    
    # 在spyder中查函数的帮助文件 ★★★★★
    help(data.pivot_table)  # pivot_table后面没有括号
    
    # 每个地区的分数线
    result1 = data.pivot_table('分数线',
                               index='地区',
                               aggfunc='mean').sort_values(by='分数线',ascending=False)
    
    # 每个地区,不同年份的分数线
    result2 = data.pivot_table('分数线',
                               index='地区',
                               columns='年份',
                               aggfunc='mean',
                               margins=True).round(0)
    
    # 不同地区,不同考生类别、不同年份的分数线
    result3 = data.pivot_table('分数线',
                               index=['地区','考生类别'],
                               columns='年份',
                               fill_value=None,
                               aggfunc='mean',
                               margins=True).round(0)
    
    # 对同一变量计算多个统计量
    result4 = data.pivot_table('分数线',
                               index='地区',
                               aggfunc=['mean','max','min','std']).round(0)
    
    # 对不同的变量计算不同的统计量
    result5 = data.pivot_table(index='地区',
                               aggfunc={'分数线':np.mean, '批次':'count'}).round(0)
    
    # =============================================================================
    # 导入excel
    # =============================================================================
    result3.to_excel('D:/python/课件/结果/高考成绩.xlsx')
    
    

    merge()

    # 导入工具包,pandas、numpy是数据分析中最常用的两个包
    import pandas as pd
    import numpy as np
    
    # =============================================================================
    # pandas.merge()方法,类似于excel中vlookup函数
    # =============================================================================
    
    # spyder查看merge的帮助文件
    help(pd.merge)  # merge后面不写()
    
    '''
    merge(left,   # 左表, dataframe格式
          right, # 右表, dataframe格式
          how: str = 'inner', # 字符串,合并方式 left right outer inner
          on=None, # 合并的关键字,如果左右两个表关键字名称相同,则用on,不同再设置left_on 和right_on
          left_on=None, #  左边表的关键字
          right_on=None,  # 右边表的关键字
          left_index: bool = False,  # 左边表是否按索引作为关键字,和left_on 二选一
          right_index: bool = False, # 右边表是否按索引作为关键字,和right_on 二选一
          sort: bool = False,  # 按合并的关键字排序
          suffixes=('_x', '_y'), # 当有相同列名区分
          copy: bool = True, # 不常用
          indicator: bool = False, # 不常用,当设置how方式为outer时,可区分数据是在左边的表,还是右边表,还是都存在,不常用
          validate=None) # 不常用
    '''
    
    # =============================================================================
    # 创建2个dataframe
    # =============================================================================
    data1 = pd.DataFrame({'姓名': ['A', 'B', 'C', 'D'],
                         '学校':['一中','一中','一中','一中'],
                         '英语': [50,60,45,987],
                         '历史': [64,39,56,88]})
    
    data2 = pd.DataFrame({'姓名': ['B', 'C', 'D', 'E','F','G','H'],
                          '学校':['一中','一中','一中','一中','一中','一中','一中'],
                          '数学': np.random.randint(10,30,7),
                          '政治': np.random.randint(10,30,7),
                          '备注':['','','','','','','']})
    
    
    # =============================================================================
    # 数据合并
    # =============================================================================
    
    # 将右边表同学的成绩匹配到左边的表,单个关键字
    resut1 = pd.merge(data1,  # 左边的表
                      data2,  # 右边的表
                      on='姓名',  # 按哪些关键子进行合并 ,如果是多个则写成列表格式 比如['',''],因为关键字在左右两个表中都为‘姓名’,所以此处用on
                      how='left')  # 合并方式,多数情况用left
    
    
    # 将右边表同学的成绩匹配到左边的表,多个关键字
    resut2 = pd.merge(data1,  # 左边的表
                      data2,  # 右边的表
                      on=['姓名','学校'],  
                      how='left')  # 合并方式
    
    # 合并后列太多,不想显示太多列信息
    resut3 = pd.merge(data1,  # 左边的表
                      data2[['姓名','数学','政治']],  # 右边的表
                      on='姓名',  
                      how='left')  # 合并方式
    
    # 将右边表同学的成绩匹配到左边的表,单个关键字,如果右边的表数据有重复的,会导致左边的表数据增加。可先去重
    resut4 = pd.merge(data1,  # 左边的表
                      #data2,
                      data2.drop_duplicates(subset='姓名'),  # 右边的表
                      on='姓名',  
                      how='left')  # 合并方式
    
    

    数据筛选与排序

    # 导入pandas工具包
    import pandas as pd
    # 读取数据
    data1 = pd.read_csv('D:/python/课件/data/dzdp_data.csv')
    
    # 删除有缺失值的数据,缺失值可能会导致筛选报错
    data1 = data1.dropna().reset_index(drop=True)
    
    # 修改列名:列名都改为中文
    data1.columns = ['客户id', '评价时间', '星级', '内容', '口味',
                     '环境', '服务', '商店id', '评分', '年', '月', 
                     '周','小时', '内容长度']
    
    
    # =============================================================================
    # 数据筛选
    # =============================================================================
    
    # =============================================================================
    # 筛选列,两个中括号
    # =============================================================================
    data2 = data1[['客户id','评价时间','口味','环境', '服务', '商店id', '评分']]
    
    
    # =============================================================================
    # #筛选行:单变量
    # =============================================================================
    # 文本
    data3 = data1[data1['服务']=='很好'] # 两个等号
    data3_re = data1[~(data1['服务']=='很好')] # 反选
    data3_re_re = data1[data1['服务']!='很好'] # 反选
    # 数值
    data3_re_re = data1[data1['内容长度']<10] 
    
    
    # =============================================================================
    # 筛选行:多变量
    # =============================================================================
    data4 = data1[(data1['服务']=='很好')&(data1['年']==2016)]  # 字符串用引号,数值不用引号  &:and 并且; | : or 或者
    #(data1['服务']=='很好')&(data1['年']==2016)
    
    # =============================================================================
    # 筛选行:单变量多种条件
    # =============================================================================
    data5 = data1[data1['服务'].isin(['好', '很好', '非常好'])]
    data6 = data1[data1['年'].isin([2015,2018])]
    
    # =============================================================================
    #loc、iloc筛选:可以筛选行 和筛选列
    # =============================================================================
    data7 = data1.loc[data1['服务']=='很好',['客户id','评价时间']]
    data7_re = data1.loc[data1['年']>2014]
    data7_re_re = data1.loc[data1['年']>2014,:]
    data7_re_re_re = data1.iloc[:5,3:10]  # 一般会用在for循环中
    
    # =============================================================================
    # str筛选:模糊匹配赛选
    # =============================================================================
    data8 = data1[data1['内容'].str.contains('北京')]  # 筛选内容字段中含“北京”两个子的数据
    data9 = data1[data1['内容'].str.contains('北京|上海')]  # 筛选内容字is段中含“北京”或者“上海”两个子的数据
    data10 = data1[data1['客户id'].str.len()>20]  # 筛选客户id长度大于20的
    data11 = data1[data1['内容'].str.startswith('广州')]  # 筛选内容以“广州”开头的
    data12 = data1[data1['客户id'].str[0]=='A']  # 筛选客户id以A开头的
    data13 = data1[data1['客户id'].str.isdigit()]  # 筛选客户id只包含数值的
    
    # =============================================================================
    # 日期筛选
    # =============================================================================
    data1.info()
    data1['评价时间'] = pd.to_datetime(data1['评价时间'])
    
    # 当日期为变量列时
    data14 = data1[data1['评价时间'].apply(lambda x: x.year == 2018)]
    data15 = data1[data1['评价时间'].apply(lambda x: x.strftime('%Y%m')=='201808')]
    data16 = data1[data1['评价时间']>'2018-9-1']
    
    
    # 当日期为索引时
    data1_copy = data1.copy()
    data1_copy.set_index('评价时间',inplace=True)
    
    # 筛选
    data17 = data1_copy.loc['2015']
    data17_re = data1_copy.loc['2015-08']  # '2015-08':'2015-10'
    data17_re_re = data1_copy.loc['2015-08-01']
    
    
    # =============================================================================
    # 高阶函数和分组后筛选:会在后期视频介绍
    # =============================================================================
    
    
    # =============================================================================
    # 排序
    # =============================================================================
    # 单字段排序
    data1.sort_values('评价时间',inplace=True)  # 默认升序排列
    data1.sort_values('评价时间',ascending=False,inplace=True)  # 改成降序
    
    # 多字段排序
    data1.sort_values(['评价时间','评分'],ascending=[False,False],inplace=True)
    
    

    总结

    改变表头

    # 是给数据多加了一个表头
    df=pd.read_csv('train.csv',names=['乘客ID','是否幸存','仓位等级','姓名','性别','年龄','兄弟姐妹个数','父母子女个数','船票信息','票价','客舱','登船港口'])
    df
    
    

    在这里插入图片描述

    # 这个才是替换表头
    df=pd.read_csv('train.csv')
    df.columns=['乘客ID','是否幸存','仓位等级','姓名','性别','年龄','兄弟姐妹个数','父母子女个数','船票信息','票价','客舱','登船港口']
    df.head()
    

    在这里插入图片描述

    更多相关内容
  • Python pandas模块

    千次阅读 2022-05-18 18:59:35
    Python的Pandas模块系统学习

    在这里插入图片描述

    1 pandas数据读取

    Pandas需要先读取表格类型的数据,然后进行分析

    在这里插入图片描述

    1.1 读取文件和基础语句:

    读取csv文件数据:

    import pandas as pd
    filepatch=r"C:\Users\radiomumm\Desktop\sucai\nba.csv"
    #读取csv文件数据
    ratings=pd.read_csv(filepatch)
    #查看文件开头几行
    print(ratings.head())
    #查看文件行列属性,(行,列)
    print(ratings.shape)
    #查看列名,返回的是一个列表
    print(ratings.columns)
    #查看索引列
    print(ratings.index)
    #查看每列数据的数据类型
    print(ratings.dtypes)
    

    读取txt文件数据,txt文件需要以行列行使储存数据:

    import pandas as pd
    filepatch=r"C:\Users\radiomumm\Desktop\sucai\nba.txt"
    #自定义读取文件,sep=设置分隔符,header=设置标题行有无,names=设置自定义列名。
    ratings=pd.read_csv(filepatch,sep="\t",header=None,names=['NAME', 'state'])
    print(ratings.head())
    

    读取excel文件数据:

    import pandas as pd
    filepatch=r"C:\Users\radiomumm\Desktop\sucai\bhlh112.xlsx"
    ratings=pd.read_excel(filepatch)
    print(ratings.head())
    

    2 pandas数据结构(dataframe & series)

    DataFrame:二维数据,整个表格,多行多列。

    Series:一维数据,代表一行或一列。包含一组数据(不同数据类型)和一组与之相关的数据标签(索引)组成。

    在这里插入图片描述

    3 创建Series或Dataframe

    3.1 series:

    3.1.1 列表创建series:

    import pandas as pd
    sl=pd.Series([1,"A",23,5.4])
    # [out]
    # 0      1     
    # 1      A     
    # 2     23     
    # 3    5.4
    # dtype: object 
    
    #获取索引
    print(sl.index)#"RangeIndex(start=0, stop=4, step=1)"
    # 获取值数列
    print(sl.values)#[1 'A' 23 5.4]
    #更换索引列,创建一个具有标签的Series.
    sl=pd.Series([1,"A",23,5.4],index=["a","b","c","d"])
    print(sl.index)#Index(['a', 'b', 'c', 'd'], dtype='object')
    

    3.1.2 字典创建series:

    #使用字典创建Series
    dictdata={"a":123,"b":3234,"c":1.2,"d":"end"}
    sl2=pd.Series(dictdata)
    print(sl2)
    # [out]
    # a     123
    # b    3234
    # c     1.2
    # d     end
    # dtype: object
    

    3.1.3 查询Series中的数据

    print(sl2["a"])#查询一个值时,返回原生数据。
    print(sl2[["a","b"]])#查询两个值时,返回一个Series。
    

    3.2 Dataframe

    3.2.1 创建Dataframe:

    ①.常见的方法为第一章中的Pandas读取excel/csv/mysql

    ②.使用多个字典文件创建Dataframe

    import pandas as pd
    dataf={"name":["xiaohong","xiaozhang","xiangqiang"],
           "age":[21,23,22],
           "gender":["female","male","female"],
           "school":["1s","3s","2s"]}
    df=pd.DataFrame(dataf)
    print(df)
    # [out]
    #          name  age  gender school
    # 0    xiaohong   21  female     1s
    # 1   xiaozhang   23    male     3s
    # 2  xiangqiang   22  female     2s
    print(df.index)#RangeIndex(start=0, stop=3, step=1)
    print(df.columns)#Index(['name', 'age', 'gender', 'school'], dtype='object')
    

    3.2.2 查询Dataframe中的数据:

    如果只查询一列、一行,返回的是Series。

    如果查询的说多列、多行,返回的是一个Dataframe。

    print(df["age"])#返回的是Series
    print(df[["age"]])#返回的是Dataframe
    print(df[["age","school"]])
    

    4 pandas数据查询

    4.1 loc和iloc的用法

    4.1.1 loc

    loc 基于行标签和列标签(x_label、y_label)进行索引,主要查询方法:

    1.使用单个labe伯查询数据

    2.使用值列表批查询

    3.使用数伯区间进行范围查询

    4.使用条件太达式查向

    5.调用函数查询

    loc先行后列,中间用逗号(,)分割。

    4.1.1.0 数据准备

    传入NBA球员薪资情况表:
    在这里插入图片描述

    import pandas as pd
    # 0.数据的预处理
    filepatch=r"C:\Users\radiomumm\Desktop\sucai\nba.csv"
    #读取csv文件数据
    df=pd.read_csv(filepatch)
    #设置列索引,inplace=True直接改变df格式
    df.set_index("NAME",inplace=True)
    #将"SALSRY"中的"$45,780,966"格式修改为"45780966"数值格式,以便于就绪操作。
    df.loc[:,"SALSRY"]=df["SALSRY"].str.replace("$","").str.replace(",","").astype("int32")
    

    4.1.1.1 使用单个label值查询数据

    # 查询"Stephen Curry, PG"的薪资
    print(df.loc["Stephen Curry, PG","SALSRY"])#返回单一值,"45780966"
    # 查询"Stephen Curry, PG"的薪资和队伍
    print(df.loc["Stephen Curry, PG",["SALSRY","TEAM"]])#返回一个Series
    

    4.1.1.2使用值列表批量查询数据

    # 查询"Stephen Curry, PG"/"James Harden, SG"/"John Wall, PG"的薪资
    print(df.loc[["Stephen Curry, PG","James Harden, SG","John Wall, PG"],"SALSRY"])#得到一个series
    
    print(df.loc[["Stephen Curry, PG","James Harden, SG","John Wall, PG"],["SALSRY","TEAM"]])#得到一个Dataframe
    

    4.1.1.3使用数值区间批量查询数据

    【区间既包含开始,也包含结束】

    print(df.loc["Stephen Curry, PG":"John Wall, PG","SALSRY"])#行index查询,前三行的薪资
    print(df.loc["Stephen Curry, PG","TEAM":"SALSRY"])#列index查询,第一行的两列数据
    print(df.loc["Stephen Curry, PG":"John Wall, PG","TEAM":"SALSRY"])#行和列同时使用区间查询
    

    4.1.1.4使用条件表达式查询

    【bool列表的长度得等于行数或者列数】

    # 查询薪资大于41018900的球员
    print(df.loc[df["SALSRY"]>41018900,:])
    # 查询薪资大于41018900的球员,且在"Los Angeles Lakers"队中。【每个条件由括号分隔】
    print(df.loc[(df["SALSRY"]>41018900)&(df["TEAM"]=="Los Angeles Lakers"),:])
    

    4.1.1.5使用函数查询

    # 直接调用lambda函数,输入整个df,然后按条件筛选。
    print(df.loc[lambda df :(df["SALSRY"]>41018900)&(df["TEAM"]=="Los Angeles Lakers"),:])
    # 编写自己的函数进行查询,所有属于"Golden State Warriors"队的球员
    def choose_maydata(df):
        return df["TEAM"]=="Golden State Warriors"
    print(df.loc[choose_maydata,:])
    

    4.1.2 iloc

    iloc 基于行索引和列索引(index,columns)都是从 0 开始

    如果数据的行标签和列标签名字太长或不容易记,则用 iloc 很方便,只需记标签对应的索引即可。

    print(df.iloc[0,2])#取出Stephen Curry, PG的薪资数据,"45780966"
    print(df.iloc[0:2])#取前两行对应数据
    print(df.iloc[:,0:2])#取前两列对应数据
    print(df.iloc[0:2,0:2])#取前两行和前两列对应数据
    print(df.iloc[[0,2],[0,1,2]])#取第一行和第三行、第一列和第四列对应的数据
    

    5 Pandas新增数据列

    【直接赋值/apply/assign/分条件赋值】

    5.0 数据预处理

    import pandas as pd
    # 0.数据的预处理
    filepatch=r"C:\Users\radiomumm\Desktop\sucai\nba.csv"
    #读取csv文件数据
    df=pd.read_csv(filepatch)
    

    5.1直接赋值

    和上文提到的修改数值方法相同,将Series格式看作为dictionary直接赋值。

    # 选中df中的"SALSRY"列,对改列进行重新赋值,赋值内容为去除"$"和","并转化为int32格式
    df.loc[:,"SALSRY"]=df["SALSRY"].str.replace("$","").str.replace(",","").astype("int32")
    # 新增列,球员上场位置。
    df.loc[:,"positions_TYPE"]=df["NAME"].str.replace("\w* \w*,","")
    # 修改球员名字后的上场位置。
    df.loc[:,"NAME"]=df["NAME"].str.replace(",.*","")
    

    5.2 df.apply方法

    这个函数需要自己实现,函数的传入参数根据axis来定,比如axis = 1,就会把一行数据作为Series的数据结构传入给自己实现的函数中,我们在函数中实现对Series不同属性之间的计算,返回一个结果,则apply函数 会自动遍历每一行DataFrame的数据,最后将所有结果组合成一个Series数据结构并返回。

    实例:添加一列实例:薪资大于40000000的为高薪,低于10500000的为底薪,否则就是正常薪资。

    def get_SALSRY(df):
        if df["SALSRY"]>=40000000:
            return "high"
        elif df["SALSRY"]<=10500000:
            return "low"
        else:
            return "normal"
    df.loc[:,"hight_low"]=df.apply(get_SALSRY,axis=1)#第0轴沿着行的垂直往下,第1轴沿着列的方向水平延伸。
    #使用value_counts()函数对该列进行计数
    x=df["hight_low"].value_counts()
    print(x)
    

    5.3 df.assign方法

    能够同时新增多个列,返回一个新列,该对象除新列外,还包含所有原始列。【assgin不会改变原有df,因此需要重新赋值】

    实例:添加一列球员人民币薪资

    df=df.assign(RMB=lambda x :x["SALSRY"]*6.72)
    

    5.4 按条件选择分组分别赋值

    按条件先选择数据,然后对这部分数据赋值新列

    实例:PG球员薪资超过30000000认为是球星。

    df["superstar"]=""
    df.loc[df["SALSRY"]>=30000000,"superstar"]="star"
    df.loc[df["SALSRY"]<30000000,"superstar"]="normal_player"
    # print(df.head(120))
    x=df["superstar"].value_counts()
    print(x)
    

    6 Pandas对缺值的处理

    三类函数完成以上操作:

    ●isnll和notnull: 检测是否是空值,可用于df和series。

    ●dropna: 丢弃、删除缺失值

      axis :删除行还是列,{0 or "index', 1 or 'columns’}, default 0
    
      how :如果等于any则任何值为空都删除,如果等于al则所有值都为空才删除。
    
      inplace :如果为True则修改当前df,否则返回新的df。
    

    ●fllna: 填充空值

       value:用于填充的值,可以是单个值,或者字典(key是列名,value是值)。
    
      method :等于il使用前一个不为空的值填充forword fll;等于bil使用后一个不为空的值填充backword fill。
    
       axis: 按行还是列填充,{0 or index', 1 or 'columns'}
    
       inplace :如果为True则修改当前df,否则返回新的df。
    

    6.0 准备数据

    录入qPCR的分析数据(excel):

    其中skiprows=num这一参数能够忽略设置的行数,即skiprows=1:忽略第一行。

    import pandas as pd
    filepatch=r"C:\Users\radiomumm\Desktop\sucai\qpcr.xlsx"
    df=pd.read_excel(filepatch,skiprows=1)#skiprows=num,忽略前num行读取。
    

    6.1检测数据集中的空值

    isnull返回的值均为True/False,适用于Dataframe和Series。

    print(df.isnull())#返回整个Datafream中True/False,对应是否为空值。
    print(df["SAMPLE"].isnull())#返回Series中True/False,对应是否为空值。
    

    notull可用于筛选所有不为空值的行列

    print(df.notnull())#返回整个Datafream中True/False,对应是否不为空值,与isnull函数相反。
    print(df["SAMPLE"].notnull())#返回Series中True/False,对应是否不为空值,与isnull函数相反。
    

    实例:返回"A1"列不为空值的所有行。

    print(df.loc[df["A1"].notnull(),:])#筛选"A1"列不为空的所有行
    

    6.2删除空值的列

    dropna函数中axis="columns"表示列删除,how="all"表示删除全为空值的列,inplace=True表示对数据集本身进行修改。

    axis参数:存在"columns"和"index"两种模式。即,一个删除列一个删除行。

    how参数:存在"all"和"any"两种模式。使用"all"时删除全部为空值模式;使用"any"时为存在空值就删除模式。

    实例:删除全部为空值的列。

    df.dropna(axis="columns",how="all",inplace=True)
    

    实例:删除全部为空值的行。

    df.dropna(axis="index",how="all",inplace=True)
    

    6.4 填充空值

    使用fillna函数对空值进行填充,需要用到inplace=True对原Dataframe进行修改。

    fillna函数原理:【df.loc[:,“A1”]=df[“A1”].fillna(“NA”)】,还类似于字典形式。

    对单一Series进行填充

    df.fillna({"A1":0},inplace=True)
    

    对多个Series进行填充

    df.fillna({"A1":"NA","A2":"NA","A3":"NA","ACT1":"NA","ACT2":"NA","ACT3":"NA"},inplace=True)#实现多行填充
    

    6.5 将某列中的空值填充为上一个元素

    这里用到了fillna中的参数:ffill(forward fill)。即使用前面不为空的值进行填充。

    实例:将NAME和SAMPLE中的缺失值进行填充

    df.loc[:,"NAME"]=df["NAME"].fillna(method="ffill")
    df.loc[:,"SAMPLE"]=df["SAMPLE"].fillna(method="ffill")
    

    6.6 将清洗好的excel保存为新的文件

    使用to_excel将数据保存为新的excel,保存时添加index=False能够避免生成行数列。

    df.to_excel(r"C:\Users\radiomumm\Desktop\sucai\qpcr_clean.xlsx",index=False)
    

    除to_excel外还有:
    在这里插入图片描述

    7 Pandas对数据进行排序

    #数据的预处理
    import pandas as pd
    filepatch=r"C:\Users\radiomumm\Desktop\sucai\nba.csv"
    df=pd.read_csv(filepatch)
    df.loc[:,"SALSRY"]=df["SALSRY"].str.replace("$","").str.replace(",","").astype("int32")
    

    7.1 Series的排序

    Series.sort_ values(ascending=True, inplace=False)

    参数:

    1. ascencding: 默认为True升序排序,为False降序排序。
    2. inplace: 是否修改原始Series。
      排序时对数值和字符串均能排序,数值默认升序,字符串默认a-z。
    print(df["SALSRY"].sort_values())#默认为True升序排序
    print(df["SALSRY"].sort_values(ascending=False))#False降序排序
    print(df["TEAM"].sort_values())#字符串同样能够排序,默认为a-z
    

    7.2 DataFrame的排序

    DataFrame.sort values(by, ascending=True, inplace=False)

    参数 :

    1. by: 字符串或者List<字符串>, 单列排序或者多列排序。
    2. ascending: bool或者List, 升序还是降序,如果是list对应by的多列。
    3. inplace: 是否修改原始DataFrame
      事实上DF是以某一列或某几列对整个数据集按行排序。
    print(df.sort_values(by="SALSRY"))#以SALSRY列对整个df进行排序,默认为True升序排序
    print(df.sort_values(by="SALSRY",ascending=False))#以SALSRY列对整个df进行排序,默认为True升序排序
    

    对df中多列值进行排列【多列排序时谁在前,优先排谁】

    print(df.sort_values(by=["TEAM","SALSRY"],ascending=False))#先排"TEAM"再排"SALSRY"
    print(df.sort_values(by=["SALSRY","TEAM"],ascending=False))
    

    排序时分别指定升序降序

    print(df.sort_values(by=["TEAM","SALSRY"],ascending=[False,True]))
    

    8 Pandas中字符串的处理

    pandas提供大量关于字符串常用方法:

    https://pandas.pydata.org/docs/reference/series.html#string-handling

    具体使用方法 :

    1. 使用方法:先获取Series的str属性, 然后在属性上调用函数。

    2. 只能在字符串列上使用,不能数字列上使用。

    3. Dataframe.上没有str属性和处理方法。

    4. Series.str并不是Python原生字符串,而是自己的一套方法,不过大部分和原生str很相似。
      本节只挑选常用的部分语句演示:

    5. 获取Series的str属性,然后使用各种字符串处理函数

    6. 使用str的startswith、contains等bool类Series可以做条件查询

    7. 需要多次str处理的链式操作

    8. 使用正则表达式的处理

    8.0 准备数据

    import pandas as pd
    filepatch=r"C:\Users\radiomumm\Desktop\sucai\nba.csv"
    df=pd.read_csv(filepatch)
    

    8.1 替换字符串中的内容

    使用replace函数,批量替换series中的特定字符串。

    print(df["SALSRY"].str.replace("$","").str.replace(",",""))
    

    8.2 使用str的startswith、contains等得到bool的Series可以做条件查询

    condition=df["NAME"].str.startswith("Stephen")
    # print((condition))#返回只含有True/False的bool series
    print(df[condition])#返回筛选结果
    

    8.3 多次替换并截取字符串中的内容

    print(df["NAME"].str.replace(", ","-").str.slice(-2))#其中slice就是切片用法,slice[-2]
    #相当于
    print(df["NAME"].str.replace(", ","-").str[-2:])#其中slice就是切片用法,slice[-2]
    

    8.4 使用正则表达式的处理

    实例:添加一列球员打什么位置

    def get_pos(x):
        name,pos=x["NAME"].split(",")
        return "{} is {}".format(name,pos)
    
    df["infor"]=df.apply(get_pos,axis=1)
    

    问题:如何还原原有的NAME信息?
    1.使用替换的方法

    df.loc[:,"infor"]=df["infor"].str.replace(" is ",",")
    

    2.使用正则表达式

    df.loc[:,"infor"]=df["infor"].str.replace(" \w\w ",",")
    

    Pandas中的axis参数如何理解?

    ●axis=0或者"index":

    如果是单行操作,就指的是某一行

    如果是聚合操作,指的是跨行cross rows

    ●axis=1或者"columns" :

    如果是单列操作,就指的是某一列

    ■如果是聚合操作,指的是跨列cross columns

    按哪个axis,就是这个axis要动起来(类似被for遍历),其它的axis保持不动

    创建3*4的dataframe:

    import pandas  as pd
    import numpy as np
    df=pd.DataFrame(np.arange(12).reshape(3,4),columns=["a","b","c","d"],index=["A","B","C"])
    

    1.单列drop删除某一列

    df.drop("a",axis=1,inplace=True)
    

    2.单行drop,删除某一行

    df.drop("A",axis=0,inplace=True)
    

    3.按axis=0/index执行mean聚合操作

    【反直觉:输出的不是每行的结果,而是每列的结果】

    可以理解为:axis=0即传入行坐标输出的是列标题的结果,而axis=1传入列坐标,输出的是行标题结果。

    实例:输出每列平均值

    print(df.mean(axis=0))
    

    实例:输出每行平均值

    print(df.mean(axis=1))
    

    4.加深理解

    实例:新增一列计算平均值

    def get_mean_columns(x):
        return (x["a"]+x["b"]+x["c"]+x["d"])/4
    df["mean1"]=df.apply(get_mean_columns,axis=1)
    

    9 Pandas中的index如何使用

    index的用途总结:

    1. 更方便的数据查询
    2. 使用index可以获得性能提升
    3. 自动的数据对齐功能
    4. 更多更强大的数据结构支持
      数据准备:
    import time
    from sklearn.utils import shuffle
    import pandas as pd
    #数据的预处理,读取csv文件数据
    filepatch=r"C:\Users\radiomumm\Desktop\sucai\nba.csv"
    df=pd.read_csv(filepatch)
    

    9.1 使用index查询数据

    由于set_index会将索引列删除,因此设置drop=False使其保留在列表内。

    9.1.1 设置 index:

    df.set_index("TEAM",inplace=True,drop=False)
    

    9.1.2 查询:

    1. 使用columns的condition的方法查询
    condition=df.loc[df["TEAM"]=="Golden State Warriors"]
    print(condition)
    

    2.使用index的方法查询,简化查询过程

    condition=df.loc["Golden State Warriors"]
    print(condition)
    

    9.2 使用index能够提升查询性能

    蓝色线:如果index是唯一的,Pandas会使用哈希表优化,查询性能为O(1)。

    绿色线:如果index不是唯一的, 但是有序,Pandas会使用二分查找算法,查询性能为O(logN)。

    黄色线:如果index是完全随机的,那么每次查询都要扫描全表,查询性能为O(N)。

    查询时间与数据是否递增间的关系图

    9.2.1 实验1:完全随机的顺序查询

    # 将数据随机打散
    df_shuffle=shuffle(df)
    # 查看数据的index是否递增
    print(df_shuffle.index.is_monotonic_increasing)#"Flase"
    # 查看数据的index是可以用哈希
    print(df_shuffle.index.is_unique)#"Flase"
    #计算时间耗费
    start=time.time()
    print(df_shuffle.loc["Cleveland Cavaliers"])#"Running time: 0.00600123405456543 Seconds"
    end=time.time()
    print('Running time: %s Seconds'%(end-start))
    

    9.2.2 实验2:将index排序后查询

    # 将随机打散数据重新排序
    df_shuffle_sorted=df_shuffle.sort_index()
    # 查看数据的index是否递增
    print(df_shuffle_sorted.index.is_monotonic_increasing)#"True"
    # 查看数据的index是可以用哈希
    print(df_shuffle_sorted.index.is_unique)#"Flase"
    #时间耗费
    start=time.time()
    print(df_shuffle_sorted.loc["Cleveland Cavaliers"])#"Running time: 0.00699615478515625 Seconds"
    end=time.time()
    print('Running time: %s Seconds'%(end-start))
    

    9.3 使用Series能够自动对齐数据

    实例:两个series相加,相同索引相加,不相同的为NA。

    s1=pd.Series([1,2,3,4],index=["a","b","c","d"])
    s2=pd.Series([4,5,6,7,8],index=["c","d","f","w","q"])
    print(s1+s2)
    

    输出为:
    a NaN

    b NaN

    c 7.0

    d 9.0

    f NaN

    q NaN

    w NaN

    9.4 使用index更多更强大的数据结构支持

    很多强大的索引数据结构

    ●Categoricallndex,基于分类数据的Index,提升性能;

    ●MutiIndex, 多维索引,用于groupby多维聚合后结果等;

    ●DatetimeIndex, 时间类型索引,强大的日期和时间的方法支持;

    10 Pandas中merge的使用方法

    Pandas的Merge,栖当于Sql的Join, 将不同的表按key关联到一个表。

    merge的语法:

    【pd.merge(left, right,how=“inner”,on=None,left_on=None,right_on=None,left_index=False,right_ndex=False,sort=True,suffixes=(“_x”,“_y”),copy=True,indicator=False,validate=None)】

    ●left/right: 要merge的dataframe或者有name的Series

    ●how: join类型, “left, 'right, ‘outer’ , ‘inner’,默认为"inner”

    ●on: join的key, left和right都需要有这个key

    ●left_on: left的dataframe或者Series的key

    ●right_on: right的dataframe或者Series的key

    ●left_index/right_index: 使用index而不是普通的column做jion

    ●suffixes: 两个元素的后缀,如果列有重名,自动添加后缀,默认是(“_x”,“_y”)

    10.1 数据集merge的使用实例

    使用网站MovieLens | GroupLens提供的电影评分数据:

    输入数据:

    10.1.0 数据的预处理,读取csv文件数据

    import pandas as pd
    #读取并重新分隔命名数据
    df_ratings=pd.read_csv(r"C:\Users\radiomumm\Desktop\sucai\ml-1m\ratings.dat",sep="::",engine="python",names="User_id::Movie_id::Ratings::Timestamp".split("::"))
    df_users=pd.read_csv(r"C:\Users\radiomumm\Desktop\sucai\ml-1m\users.dat",sep="::",engine="python",names="User_id::Gender::Age::Occupation::Zip-code".split("::"))
    df_movies=pd.read_csv(r"C:\Users\radiomumm\Desktop\sucai\ml-1m\movies.dat",sep="::",engine="python",names="Movie_id::Title::Genres".split("::"))
    print(df_movies.head(20))
    print(df_users.head(20))
    print(df_ratings.head(20))
    

    10.1.1 Pandas中merge的使用方法

    1.处理评分(df_ratings)与用户(df_users)之间的join。

    left_on/right_on指的是按照两个数据集的指定key合并,how="inner"表示两组数据均包含选取key才保留。

    df_ratings_users=pd.merge(df_ratings,df_users,left_on="User_id"
                              ,right_on="User_id"
                              ,how="inner")
    print(df_ratings_users.head(20))
    

    2.处理评分用户(df_ratings_users)与电影信息(df_movies)之间的join。

    df_ratings_users_movies=pd.merge(df_ratings_users,df_movies,left_on="Movie_id"
                              ,right_on="Movie_id"
                              ,how="inner")
    print(df_ratings_users_movies.head(120))
    

    10.2 Pandas中merge的数据对齐关系

    以下关系要正确理解:

    ●one-to-one:一对一关系,关联的key都是唯一的。

    ■比如(学号,姓名) merge (学号,年龄),结果条数为: 1*1

    ●one-to-many:一对多关系, 左边唯一key, 右边不唯一key。

    ■比如(学号,姓名) merge (学号, [语文成绩、数学成绩、英语成绩),结果条数为: 1*N

    ●many-to-many:多对多关系,左边右边都不是唯一的。

    比如(学号,[语文成绩、数学成绩、英语成绩]) merge (学号, [篮球、足球、乓球]),结果条数为: M*N

    实例:

    10.2.1 one-to-one一对一关系的merge

    在这里插入图片描述

    left=pd.DataFrame({"sno":[232,211,231,413],
                          "age":[21,23,22,24]})
    right=pd.DataFrame({"sno":[232,211,231,413],
                          "name":["xiaoz","xiaos","xiaow","xiaod"]})
    pd_sum=pd.merge(right,left,on="sno")
    print(pd_sum)
    

    10.2.2 one-to-many一对多关系的merge

    在这里插入图片描述

    left=pd.DataFrame({"sno":[232,211,231,413],
                          "name":["xiaoz","xiaos","xiaow","xiaod"]})
    right=pd.DataFrame({"sno":[232,232,232,211,211,211,231,231,231,413],
                          "grade":["语文99","数学92","英语87","语文92","数学32","英语17",
                                  "语文29","数学34","英语27","英语97"]})
    pd_sum=pd.merge(right,left,on="sno")
    print(pd_sum)
    

    10.2.3 many-to-many多对多关系的merge

    在这里插入图片描述

    left=pd.DataFrame({"sno":[232,211,211,231,231,231,413],
                          "爱好":["篮球 ","篮球","排球","台球","电竞","看球","游戏"]})
    right=pd.DataFrame({"sno":[232,232,232,211,211,211,231,231,231,413],
                          "grade":["语文99","数学92","英语87","语文92","数学32","英语17",
                                  "语文29","数学34","英语27","英语97"]})
    pd_sum=pd.merge(right,left,on="sno")
    print(pd_sum)
    

    10.3 如何理解left join、right join、inner join和outer join的区别

    left join:以左边数据集为准,左数据集完全保留,右边数据集为空。

    right join:右边数据集完全保留,左边数据集为空。

    inner join:左右数据集交集。

    outer join:左右数据集合集。

    在这里插入图片描述

    实例:

    import pandas as pd
    left=pd.DataFrame({"key":["K1","K2","K3","K4"],
                       "爱好1":["篮球 ","篮球","排球","台球"],
                       "B":["B1","B2","B3","B4"]})
    right=pd.DataFrame({"key":["K3","K4","K5","K6"],
                       "爱好2":["篮球1 ","篮球2","排球3","台球4"],
                       "A":["A1","A2","A3","A4"]})
    

    1.inner join,默认【左右两个数据集都存在时才输出】

    print(pd.merge(left,right,how="inner"))
    

    2.left join,【左边的都会出现在结果里,右边的如果无法匹配则为Null】

    print(pd.merge(left,right,how="left"))
    

    3.right join,【右边的都会出现在结果里,左边的如果无法匹配则为Null】

    print(pd.merge(left,right,how="right"))
    

    4.outer join,【左右两个数据集都会出现在结果里,匹配不上的为Null】

    print(pd.merge(left,right,how="outer"))
    

    10.4 如果出现非Key的字段重名怎么办

    实例 :

    import pandas as pd
    left=pd.DataFrame({"key":["K1","K2","K3","K4"],
                       "爱好":["篮球 ","篮球","排球","台球"],
                       "B":["B1","B2","B3","B4"]})
    right=pd.DataFrame({"key":["K3","K4","K5","K6"],
                       "爱好":["篮球1 ","篮球2","排球3","台球4"],
                       "A":["A1","A2","A3","A4"]})
    

    Pandas默认处理方法:会在 相同key后加上"_x"和"_y"

    print(pd.merge(left,right,on="key"))
    

    可以指定后缀:

    print(pd.merge(left,right,on="key",suffixes=("_left","_right")))
    

    11 Pandas实现数据的合并concat

    批量合并相同格式的Excel、给DataFrame添加行、 给DataFrame添加列。

    一句话说明concat语法:

    ●使用某种合并方式(innerlouter)

    ●沿着某个轴向(axis=0/1)

    ●把多个Pandas对象(DataFrame/Series)台并成一个。

    11.1 使用Pandas.concat合并数据

    concat语法:

    pandas.concat(objs, axis=0, join= “outer”, ignore_ index=False)

    ●objs:一个列表,内容可以是DataFrame或者Series,可以混合

    ●axis:默认是0代表按行合并,如果等于1代表按列合并

    ●join: 合并的时候索引的对齐方式,默认是outer join, 也可以是inner join

    ●ignore. index: 是否忽略原来來的数据索引。

    11.1.0 数据准备

    import pandas as pd
    import warnings
    warnings.filterwarnings("ignore")#忽略报警
    
    df1=pd.DataFrame({"A":["A0","A1","A2","A3","A4","A5"],
                      "B":["B0","B1","B2","B3","B4","B5"],
                      "C":["C0","C1","C2","C3","C4","C5"],
                      "D":["D0","D1","D2","D3","D4","D5"],
                      "E":["E0","E1","E2","E3","E4","E5"],})
    df2=pd.DataFrame({"A":["A10","A11","A12"],
                      "B":["B10","B11","B12"],
                      "C":["C10","C11","C12"],
                      "D":["D10","D11","D12"],
                      "E":["E10","E11","E12"],
                      "F":["F10","F11","F12"],})
    

    11.1.1 相同字段的首位相接,对应不上的的列会自动补充为Null

    concat默认参数为:axis=0,join=outer,ignore_index=False

    dfs=[df1,df2]
    df_sum=pd.concat(dfs)
    print(df_sum)
    # 在汇总表前加上特定的key
    df_sum=pd.concat(dfs,keys=["一月","二月"])
    print(df_sum)
    
    #ignore_index=True能够忽略数据集原本的索引,并重新设置索引
    df_sum=pd.concat(dfs,ignore_index="True")
    print(df_sum)
    
    #使用join="inner"过滤掉不匹配的列
    df_sum=pd.concat(dfs,ignore_index="True",join="inner")
    print(df_sum)
    

    11.1.2 横向表格合并(行对齐),对应不上的的行会自动补充为Null

    df_sum=pd.concat(dfs,axis=1)
    print(df_sum)
    

    11.1.3 此外该功能类似于传入新列

    #添加一列新的series
    s1=pd.Series(list(range(4)),name="G")
    df_sum=pd.concat([df1,df2,s1],axis=1)
    print(df_sum)
    #添加多列新的series
    s2=df1.apply(lambda x:x["A"]+"_CG",axis=1)
    s2.name="H"
    df_sum=pd.concat([df1,s2,s1],axis=1)
    print(df_sum)
    

    11.2 使用append()合并数据

    append语法:

    DataFrame.append(other, ignore_index=False)

    append只有按行合并,没有按列合井.相当于concat按行的简形式。

    ●other: 单个datafrema、 series、 dict, 或者列表

    ●ignore_ index: 是否忽略掉原来的数据索引

    11.2.0 数据准备

    df1=pd.DataFrame({"A":[1,2],
                      "B":[3,4]})
    df2=pd.DataFrame({"A":[5,6],
                      "B":[7,8]})
    

    11.2.1 使用append函数对一个DF添加另一个DF

    df_sum=df1.append(df2,ignore_index=True)#忽略之前的索引
    print(df_sum)
    

    11.2.2 如何一行一行给DF新增数据

    低性能版本,使用for循环【df每次都会重新赋值,如果数据很多会造成卡死】

    df=pd.DataFrame(columns=["A"])
    for i in range(5):
        df=df.append({"A":i},ignore_index=True)
    print(df)
    

    高性能版本,使用for循环

    df=pd.concat([pd.DataFrame([i],columns=["A"])for i in range(5)],ignore_index=True)
    print(df)
    

    如何理解merge( )、concat( )和append( ) 三个函数间的区别?

    Pandas提供了concat,merge,join和append四种方法用于dataframe的拼接,其区别如下:

    在这里插入图片描述

    详见:(13条消息) Pandas拼接操作(concat,merge,join和append)的区别_Yale曼陀罗的博客-CSDN博客_concat和append的区别

    12 Pandas批量拆分与合并Excel文件

    实例:

    1.将一个大的Excel拆分成多个Excel

    2.将多个小Excel合并成一个大的Excel并记录来源

    12.0 准备数据,

    12.0.1 创建工作文件夹和存放文件夹

    work_dir="C:/Users/radiomumm/Desktop/sucai"
    splits_dir=f"{work_dir}/splits"
    import os
    if not os.path.exists(splits_dir):
        os.mkdir(splits_dir)
        pass
    

    12.0.2 读取Excel到Pandas

    import pandas as pd
    #sheet_name=""可以指定读取sheet
    df_source=pd.read_excel(r"C:\Users\radiomumm\Desktop\sucai\SNP_choose.xlsx",sheet_name="ALL")
    print(df_source.index)#RangeIndex(start=0, stop=79958, step=1)
    print(df_source.shape)#(79958, 29),该列表存在79958行,29列。
    

    12.1 将一个大的excel拆分为多个小excel

    ① 使用df.iloc方法,将一个大的daframe, 拆分成多个小dataframe

    ② 将使用dataframe.to_ excel保存每个小Excel

    12.1.1 计算拆分后的每个excel的行数

    #拆分后的excel会分给一下用户:
    user_names=["A","B","C","D","E","F","G"]
    # 每个人的任务量
    split_size=df_source.shape[0]//len(user_names)
    if df_source.shape[0]%len(user_names)!=0:
        split_size+=1
        pass
    # print(split_size)
    

    12.1.2 拆分成为多个dataframe

    df_subs=[]
    for idx,user_name in enumerate(user_names):
        #每个人开始的索引,0*split_size
        begin=idx*split_size
        #每个人结束的索引
        end=begin+split_size
        #使用iloc实现拆分
        df_sub=df_source.iloc[begin:end]
        #将每个子df存入列表
        df_subs.append((idx,user_name,df_sub))#将脚标、分配人姓名、和表信息存入元组
    

    12.1.3 拆分成为多个dataframe

    for idx,user_name,df_sub in df_subs:
        filename=f"{splits_dir}/aaaaa_{idx}_{user_name}.xlsx"
        df_sub.to_excel(filename,index=False)
        pass
    

    12.2 将多个小的excel合并为一个大excel

    12.2.1 遍历文件夹,得到要合并的Excel文件列表

    import os
    import pandas as pd
    excel_names=[]
    splits_path=r"C:\Users\radiomumm\Desktop\sucai\splits"
    for excel_name in os.listdir(splits_path):
        excel_names.append(excel_name)
    # print(excel_names)
    

    12.2.2 分别读取到dataframe,给每个df添加一列用于标记来源

    df_list=[]
    for excel_name in excel_names:
        #获取每个excel的路径名称
        excel_path=f"{splits_path}/{excel_name}"
        df_split=pd.read_excel(excel_path)
        #将文件名替换好后得到“0_A”格式,使用切片[2:0]从第二个元素开始取
        username=excel_name.replace("aaaaa_","").replace(".xlsx","")[2:]
        # print(username,excel_name)
        # 添加一列用户名
        df_split["username"]=username
        df_list.append(df_split)
        pass
    

    12.2.3 使用pd.concat进行df批量合并

    # print(df_concat.shape)
    # print(df_concat["username"].value_counts())
    # 4.将合并后的dataframe输出到excel
    df_concat.to_excel(r"C:\Users\radiomumm\Desktop\sucai\df_concat.xlsx",index=False)
    

    13. Pandas怎样实现groupby分组统计

    类似SQL:

    select city.max(temperature) from city. weather group by city

    groupby:先对数据分组,然后在每个分组上应用聚合函数、转换函数。

    本次演示:

    一、分组使用聚 合函数做数据统计

    二、遍历groupby的结果理解执行流程

    三、实例分组探索NBA数据

    13.0 数据准备

    import pandas as pd
    import numpy as np
    
    filepatch=r"C:\Users\radiomumm\Desktop\sucai\nba.csv"
    df=pd.read_csv(filepatch)
    df.loc[:,"SALSRY"]=df["SALSRY"].str.replace("$","").str.replace(",","").astype("int32")
    def get_pos(x):
        name,pos=x["NAME"].split(",")
        return pos
    df["infor"]=df.apply(get_pos,axis=1)
    

    13.1 分组使用聚合函数做数据统计

    13.1.1 单个列groupby,查询所有数据列统计

    df.groupby("TEAM").sum()
    
    1. groupby中"TEAM"列成为数据的索引列。
    2. sum函数会将df中的数字形式列按列合并,字符串格式自动忽略。

    13.1.2 多个列groupby,查询所有数据列统计

    groupby中"TEAM"列和"infor"列成为数据的多级索引列。

    df.groupby(["TEAM","infor"]).sum()
    

    去除索引,变为普通的列

    df.groupby(["TEAM","infor"],as_index=False).sum()
    

    13.1.3 同时查看多种数据统计

    df.groupby("TEAM").agg([np.sum,np.mean,np.std])
    

    查看特定数据列的统计情况

    df.groupby("TEAM")["SALSRY"].agg([np.sum,np.mean,np.std])
    

    或者

    df.groupby("TEAM").agg([np.sum,np.mean,np.std])["SALSRY"]
    

    13.1.4 不同列使用不同的聚合函数

    df.groupby("TEAM").agg({"RK":np.sum,"SALSRY":np.mean})
    

    13.2 遍历groupby

    13.2.1 遍历单个列聚合的分组

    team=df.groupby("TEAM")
    print(team)#"<pandas.core.groupby.generic.DataFrameGroupBy object at 0x0000021A2A987A00>"
    

    以上格式可以直接使用for遍历

    for teamid,infor in team:
        print(teamid)
        print(infor)
    

    使用get_group函数获取单个分组

    team.get_group("Denver Nuggets")
    

    13.2.2 遍历多个列聚合分组

    team=df.groupby(["TEAM","infor"])
    for teamid,inforpos in team:
        print(teamid)
        print(inforpos)
        可以看到,teamid是一个元组,包含了分组情况。
    

    使用get_group函数获取单个分组

    team.get_group(("Denver Nuggets"," PG"))
    

    查询group后的某几列,生成Series或者DF

    print(team["RK"])#"<pandas.core.groupby.generic.SeriesGroupBy object at 0x0000014EA4467AC0>"
    for teamid,inforpos in team["RK"]:
        print(teamid)
        print(inforpos)
    

    13.3 实例:

    1.按照队伍分类后查看每队最高薪球员,并画出柱状图

    plt.xticks(rotation=90)设置x轴 标签倾斜度,plt.show( )用于显示。

    import matplotlib.pyplot as plt
    moneymax=df.groupby("TEAM",as_index=False)["SALSRY"].max()
    # print(moneymax.head(20))
    x=moneymax["TEAM"]
    y=moneymax["SALSRY"]
    plt.figure(figsize=(10,6))
    # plt.plot(moneymax)
    plt.bar(x,y,width=0.5,align="center",alpha=0.8)
    plt.xticks(rotation=90)
    plt.show()
    

    2.按照队伍分类后查看每队最高、低薪球员和排名总和,并画出折线图

    data=df.groupby("TEAM").agg({"RK":np.sum,"SALSRY":[np.max,np.min]})
    # 使用matplotlib画图
    plt.plot(data)
    plt.xticks(rotation=90)
    plt.legend()
    plt.show()
    # 使用Pandas画图
    data.plot()
    plt.xticks(rotation=90)
    plt.show()
    

    14 Pandas的分层索引Multilndex的应用

    为什么要学习分层索引Mutilndex?

    ●分层索引:在一个轴向上拥有多个索引层级,可以表达更高维度数据的形式。

    ●可以更方便的进行数据筛选,如果有序则性能更好。

    ●groupby等操作的结果,如果足多KEY,结果是分层索引,需要会使用。

    ●一般不需要白己创建分层索引(Multilndex有构造函数但一般不用)

    本次演示提纲:

    一、Series的分层索引Multilndex

    二、Series有多层索引怎样筛选数据?

    三、DataFrame的多层索引Multilndex

    四、DataFrame有多层索引怎样筛选数据?

    14.0 数据准备

    https://cn.investing.com/网站下载多个公司股票信息,并合并为一个csv文件:

    import pandas as pd
    workdir="C:/Users/radiomumm/Desktop/sucai"
    dfbaba_path=f"{workdir}/groupby/BABA历史数据.csv"
    dfbilbil_path=f"{workdir}/groupby/BILI历史数据.csv"
    dfbaidu_path=f"{workdir}/groupby/BIDU历史数据.csv"
    dfjd_path=f"{workdir}/groupby/JD历史数据.csv"
    dfnf_path=f"{workdir}/groupby/NFLX历史数据.csv"
    dfbaba=pd.read_csv(dfbaba_path)
    dfbilbil=pd.read_csv(dfbilbil_path)
    dfbaidu=pd.read_csv(dfbaidu_path)
    dfjd=pd.read_csv(dfjd_path)
    dfnf=pd.read_csv(dfnf_path)
    dfbaba.loc[:,"名字"]="baba"
    dfbilbil.loc[:,"名字"]="bilbil"
    dfbaidu.loc[:,"名字"]="baidu"
    dfjd.loc[:,"名字"]="jingdong"
    dfnf.loc[:,"名字"]="nelfx"
    dfs=[dfbaba,dfbaidu,dfbilbil,dfjd,dfnf]
    dfall=pd.concat(dfs,ignore_index=True)
    
    dfall.to_csv(f"{workdir}/groupby/汇总.csv",encoding="gbk",index=False)
    

    查看数据基本信息 :

    # 查看数据结构
    print(dfall.shape)#"(25, 8)"
    # 查看公司名字
    print(dfall["名字"].unique())#"['baba' 'baidu' 'bilbil' 'jingdong' 'nelfx']"
    # 查看索引
    print(dfall.index)
    

    14.1 series的分层索引Multilndex

    使用groupby函数分组

    ser=dfall.groupby(["名字","日期"])["收盘"].mean()
    print(ser)#多维索引中,空白意味着和上面的值一致。
    print(ser.index)#MultiIndex,列表内包含元组,元组中包含两个分组对象。
    

    使用unstack函数降低索引层次,将二级或次级索引变为列,原本的series变为dataframe。

    ser.unstack()
    

    使用reset_index函数将分组索引还原,变为dataframe,前两列为多层搜索引,后一列为索引的值列。

    ser.reset_index()
    

    14.2 series存在多层索引Multilndex怎样筛选

    使用loc函数进行索引,可以索引第一层或多层。

    print(ser.loc["bilbil"])
    print(ser.loc["bilbil","2022年5月2日"])
    

    跳过第一层筛选第二层时需要以下两种格式

    print(ser.loc[:,"2022年5月2日"])
    print(ser.loc[slice(None),"2022年5月2日"])
    

    14.3 Dataframe的多层索引Multilndex

    使用set_index对Dataframe进行分层索引

    dfall.set_index(["名字","日期"],inplace=True)
    print(dfall)
    

    对索引进行排序,先按照第一层索引排序

    dfall.sort_index(inplace=True)
    print(dfall)
    

    14.4 Dataframe存在多层索引Multilndex怎样筛选

    【重点理解】:

    ●元组(key1,key2)代表筛选多层索引,其中key1是索引第一级, key2是第二级, 比如key1=“jingdong”, key2=“2019-10-02”

    ●列表[key1,key2]代表同- 层的多个KEY,其中key1和key2是并列的同级索引,比如key1=“jingdong”, key2=“BIDU”

    14.4.1常规筛选两个层级

    只筛选第一层的某个值

    print(dfall.loc["baidu"])
    

    筛选多层索引的所有列,传入元组

    print(dfall.loc[("baidu","2022年5月6日"),:])
    

    筛选多层索引的特定列,传入元组

    print(dfall.loc[("baidu","2022年5月6日"),"交易量"])
    

    14.4.2 同层的并列筛选

    同一层多个索引值的筛选,取出两个对像

    print(dfall.loc[["baidu","bilbil"],:])
    

    混合筛选,两个第一层索引值和一个第二层索引值

    print(dfall.loc[(["baidu","bilbil"],"2022年5月6日"),:])
    

    混合索引只输出一列

    print(dfall.loc[(["baidu","bilbil"],"2022年5月6日"),"涨跌幅"])
    

    多层混合

    print(dfall.loc[(["baidu","bilbil"],["2022年5月5日","2022年5月6日"]),"涨跌幅"])
    

    需要只对第二层索引进行筛选,保留一层索引的方法

    print(dfall.loc[(slice(None),["2022年5月5日","2022年5月6日"]),"涨跌幅"])
    

    恢复索引为普通的列

    dfall.reset_index(inplace=True)
    print(dfall)
    

    15 Pandas的数据转换函数map、apply、applymap

    数据转换函数对比: map、apply、 aplymap:

    1. map:只用于Series,实现每个值->值的映射。

    2. apply:于Series实现每个值的处理,用于Dataframe实现某个轴的Series的处理。

    3. applymap:只能用于DataFrame,用于处理该DataFrame的每个元素。

    15.1 map用于Series值的转换

    实例:将股票代码转换成中文名字

    15.1.0数据准备

    Series.map(dict)或者Serise.map(function)均可。
    from ast import Lambda
    import pandas as pd
    path=r"C:\Users\radiomumm\Desktop\sucai\groupby\汇总.csv"
    df=pd.read_csv(path,encoding="gbk")
    print(df.head(20))
    #查看名字列的内容
    print(df["名字"].unique())
    

    准备字典

    dict_company_name={"BAIDU":"百度",
                       "BABA":"阿里巴巴",
                       "BILBIL":"哔哩哔哩",
                       "JINGDONG":"京东",
                       "NELFX":"奈飞"}
    

    15.1.1 map函数用于Series的转化

    方法一:map函数传递一个dict

    df['公司']=df["名字"].str.upper().map(dict_company_name)
    print(df.head(20))
    

    方法二:map函数传入一个函数【function的参数时series的每个元素值】

    df['公司']=df["名字"].map(lambda x:dict_company_name[x.upper()])
    print(df.head(20))
    

    15.2 apply用于Series和Dataframe的转化

    ●Series.apply(function),函数的参数是series每个值,与series的map函数十分相似

    df['公司']=df["名字"].apply(lambda x:dict_company_name[x.upper()])
    print(df.head(20))
    

    ●DataFrame.apply(function),函数的参数是Series

    df['公司']=df.apply(lambda x:dict_company_name[x["名字"].upper()],axis=1)
    print(df.head(20))
    

    【tips】:
    apply是在Dataframe中调用;

    Lambda的参数x是series,由于指定了asix=1所以Series的key是列名,可以用下x[“”]获取

    15.3 applymap用于Dataframe所有值的转化

    实例:

    将收盘、开盘、高、低、交易量的小数改为整数

    sub_df=df[["收盘","开盘","高","低","交易量"]]
    sub_df.loc[:,"交易量"]=df["交易量"].str.replace("M","").astype("float64")
    sub_df.applymap(lambda x:int(x))
    print(sub_df)
    

    对原有Dataframe值进行批量修改

    df.loc[:,["收盘","开盘","高","低","交易量"]]=sub_df.applymap(lambda x:int(x))
    print(df)
    

    16 Pandas怎样对每个分组(groupby)应用apply函数

    补充:

    1.Pandas的Groupby遵从三个模式,split、apply、combine模式。

    在这里插入图片描述

    事实上Split就是Pandas中的groupby,apply函数由我们自己控制,可以是一个内置函数也可以自己定义,apply返回值再由Pandas进行combine(拼接)获得输出结果。

    2.归一化就是把数据经过处理后使之限定在一定的范围内。比如通常限制在区间[0, 1]或者[-1, 1]

    一种归一化公式

    groupby.apply(function)

    • function的第一个参数为Dataframe
    • 自己写函数的话function返回结果可以是df、series、单个值,甚至和输入的Dataframe没有关系。

    16.1 实例演示:

    1.怎样对数值列按分组进行归一化?

    演示:用户对电影评分的归一化

    16.1.0 数据准备

    import pandas  as pd
    ratings=pd.read_csv(r"C:\Users\radiomumm\Desktop\sucai\ml-1m\ratings.dat",
                        sep="::",
                        engine="python",
                        names="User_id::Movie_id::Ratings::Timestamp".split("::"))
    print(ratings.head())
    

    16.1.1 按照用户id分类,并实现归一化

    def ratings_norm(df):
        min_value=df["Ratings"].min()
        max_value=df["Ratings"].max()
        df["ratings_norm"]=df["Ratings"].apply(
            lambda x:(x-min_value)/(max_value-min_value))
        return df
    ratings=ratings.groupby("User_id").apply(ratings_norm)
    print(ratings[ratings["User_id"]==1].head())
    16.1.2 怎样取每个分组的TOPN数据?
    def get_topN(df,topn):
        return df.sort_values(by="Ratings")[["User_id","Ratings"]][-topn:]
    
    print(ratings.groupby("User_id",as_index=False E  ).apply(get_topN,2).head(20))
    

    17 Pandas的stack和pivot实现数据透视

    将列式数据变成二维交叉形式,便于分析,叫做重塑或透视
    在这里插入图片描述

    左侧列表有利于数据增减,而右侧 数据利于数据处理和查找。

    17.1 stack、unstack、pivot的语法

    stack: DataFrame.stack(level=-1, dropna=True),将columh变成index,类似把横放的书籍变成竖放。

    level=-1代表多层索引的最内层,可以通过==0、1、 2指定多层索引的对应层。
    在这里插入图片描述

    unstack: DataFrame.unstack(level=-1, fill value=None), 将index变成column,类似把竖放的书籍变成横放 。
    在这里插入图片描述

    pivot: DataFrame.pivot(index=None, columns=None, values=None),指定index、columns. values实现二维透视。

    在这里插入图片描述

    实例:统计得到"电影评分数据集",每个月份的每个分数被评分多少: (月份、 分数1~5、次数)

    17.0 数据准备

    import pandas  as  pd
    import numpy as np
    
    df=pd.read_csv(r"C:\Users\radiomumm\Desktop\sucai\ml-1m\ratings.dat",
                        sep="::",
                        engine="python",
                        names="User_id::Movie_id::Ratings::Timestamp".split("::"))
    
    

    17.2 经过统计得到多维度指标数据

    对日期进行处理

    df["pdata"]=pd.to_datetime(df["Timestamp"],unit="s")
    # print(df.head(20))
    

    实现数据统计,dt.month是按月份分组

    df_groupby=df.groupby([df["pdata"].dt.month,"Ratings"])["User_id"].agg(pv=np.sum)
    # print(df_groupby.head(20))
    

    以上格式想要绘制横坐标为月份纵坐标为评分次数趋势是无法实现的,需要变化每个评分为一列才能实现

    17.3 使用unstack实现数据维透视

    df_stack=df_groupby.unstack()
    print(df_stack.head(20))
    #绘图
    import matplotlib.pyplot as plt
    df_stack.plot()
    plt.show()
    #返回原有格式
    df_unstack=df_stack.stack()
    

    17.4 使用pivot简化透视

    df_reset=df_groupby.reset_index()
    # print(df_reset.head(20))
    df_pivot=df_reset.pivot("pdata","Ratings","pv")#该方法与上文中的unstack相同
    # print(df_pivot.head(20))
    
    展开全文
  • Pandas模块的核心操作对象就是序列(Series)和数据框(DataFrame)。 1、构造序列 使用如下方式实现: 通过同质的列表或元组构建。 通过字典构建。 通过Numpy中的一维数组构建。 import pandas as ...

    目录

    一、序列与数据框的构造

     1、构造序列

    2、构造数据框

    二、外部数据的读取

    1、文本文件的读取

    2、电子表格的读取

    pd.read_excel参数介绍:

    三、数据类型转换及描述统计

    四、字符与日期数据的处理

    五、常用的数据清洗方法

    1、重复观测处理

    2、缺失值处理

    3、异常值处理

    六、数据子集的获取

    七、透视表功能

    八、表之间的合并与连接

    九、分组聚合操作


    一、序列与数据框的构造

    Pandas模块的核心操作对象就是序列(Series)和数据框DataFrame)。

     1、构造序列

    使用如下方式实现:

    通过同质的列表或元组构建。

    通过字典构建。

    通过Numpy中的一维数组构建。

    import pandas as pd
    import numpy as np
    data1=pd.Series([2.8,3.01,8.99,8.59,5.18])
    data2=pd.Series({'北京':2.8,'上海':3.01,'广东':8.99,'江苏':8.59,'浙江':5.18})
    data3=pd.Series(np.array((2.8,3.01,8.99,8.59,5.18)))
    print(data1)
    print(data2)
    print(data3)

    通过 Series函数将列表、字典和一维数组转换为序列的过程。
    构造的序列结果都是第一个打印的样式。
    该样式会 产生两列,
    第一列属于序列的行索引(可以理解为行号),自动从0 开 始,第二列才是序列的实际值。
    通过字典构造的序列就是第二个打印样式,仍然包含两列,所不同的是第一列不再是行号,而是具体的行名称 (label),对应到字典中的键,第二列是序列的实际值,对应到字典中 的值。

    序列与一维数组有极高的相似性.

    • 不同的是,序列会有更多的其他处理方法。
    • 下面通过几个 具体的例子来加以测试:
    print('行号风格的序列:\n',data1[[0,3,4]],'\n')
    print('行名称风格的序列:\n',data2[[0,3,4]],'\n')
    print('行名称风格的序列: \n',data2[['上海','江苏','浙江']],'\n')
    print('通过numpy函数:\n',np.log(data1),'\n')
    print('通过numpy函数:\n',np.mean(data1),'\n')
    print('通过序列的方法:\n',data1.mean(),'\n')

            如果需要对序 列进行数学函数的运算,一般首选numpy模块,因为Pandas模块在这方 面比较缺乏;如果是对序列做统计运算,既可以使用numpy模块中的函 数,也可以使用序列的“方法,作者一般首选序列的方法,因为序列 的“方法更加丰富,如计算序列的偏度、峰度等,而Numpy是没有这样的函数的。

    这里稍微介绍一下序列的方法,就不演示了:

    ①检查缺失值;

    Series名.isnull()  和  Series名.notnull()   
    isnull()   判断索引对应的值是否为空,若为空,返回True。语句返回值为Series类型。

    notnull()   判断索引对应的值是否为非空,若为空,返回False。

    ②通过索引获取数据;

    获取索引的方法:Series名.index

    获取值的方法:   Series名.values

    2.1 获取单个数据

    ① 通过下标获取        Series名[索引号]  

    ② 通过标签名获取    Series名[标签名]

    2.2 获取多个数据

    ① 通过下标获取       Series名[[索引号1,索引号2]]    #获取索引号1和2对应的数据

    ② 通过标签名获取    Series名[[标签名1,标签名2]]  

    2.3 切片获取数据

    ① 通过下标获取        Series名[索引号1:索引号2]      #下标切片顾头不顾尾

    ② 通过标签名获取    Series名[标签名1:标签名2]      #标签名切片顾头顾尾

    ③布尔索引;

    Series名[条件判断]       

    布尔索引可理解为True和False。

    如:

    s11 = s10[s10>3] #取出s10的值大于3的数据

    ④name属性;

    改变对象的名称:        Series名.name = 自定义名称

    改变对象的索引名称: Series名.index.name = 自定义名称

    ⑤读取前几行数据;

    Series名.head()        # 默认读取前5行数据

    Series名.head(n)      # 也可自己指定读取前n行

    ⑥读取后几行数据。

    Series名.tail()       # 默认读取后5行数据

    Series名.tail(n)     # 也可自己指定读取后n行

    感兴趣的可以自己去查还有很多的呢

    好了,回归主题,继续介绍pandas

    2、构造数据框

    • 数据框中可以存放不同数据类型的序列
    • 而数组和序列则没有这样的优势,因为它们只能存放同质数据。

    应用如下方式:

    • 通过嵌套的列表或元组构造。
    • 通过字典构造。
    • 通过二维数组构造。
    • 通过外部数据的读取构造。
    # 构造数据框
    data1=pd.DataFrame([['张三','23','男'],['李四','27','女'],['王二','26','女']])
    data2=pd.DataFrame({'姓名':['张三','李四','王二'],'年龄':['23','27','26'],'性别':['男','女','女']})
    data3=pd.DataFrame(np.array([['张三',23,'男'],['李四','27','女'],['王二','26','女']]))
    print('嵌套列表构造数据框:\n',data1)
    print('字典构造数据框:\n',data2)
    print('二维数组构造数据框: \n',data3)

    如果需要手工构造数据框的话,一般首选字典方法。因为字典转换数据框时有具体的变量名

     二、外部数据的读取

            很显然,每次通过手工构造数据框是不现实的,在实际工作中,更多的情况则是通过Python读取外部数据集,这些数据集可能包含在本地 的文本文件(如csvtxt等),接下来介绍读取外部文件。

    1、文本文件的读取

            当要读取外部文件时。一般使用 Pandas模块中的read_table函数或read_csv函数。这里的并不是指每 个函数只能读取一种格式的数据,而是这两种函数均可以读取文本文件的数据。

    这里主要介绍pd.read_table,因为它们的参数都是差不多的。

    pd.read_table(filepath_or_buffer,sep='\t',header='infer',names=None,                                
                  index_col=None,usecols=None,dtype=None,converters=None,
                  skiprows=None,skipfooter=None,nrows=None,na_values=None,            
                  skip_blank_lines=True,parse_dates=False,thousands=None,
                  comment=None,encoding=None)

    pd.read_table参数介绍:

    filepath_or_buffer指定txt文件或csv文件所在的具体路径。

    sep指定原数据集中各字段之间的分隔符,默认为Tab制表符。

    header是否需要将原数据集中的第一行作为表头,默认将第一 行用作字段名称。

    names如果原数据集中没有字段,可以通过该参数在数据读取 时给数据框添加具体的表头。

    index_col指定原数据集中的某些列作为数据框的行索引(标 签)。

    usecols指定需要读取原数据集中的哪些变量名。

    dtype读取数据时,可以为原数据集的每个字段设置不同的数 据类型。

    converters通过字典格式,为数据集中的某些字段设置转换函 数。

    skiprows数据读取时,指定需要跳过原数据集开头的行数。

    skipfooter数据读取时,指定需要跳过原数据集末尾的行数。

    nrows指定读取数据的行数。

    na_values指定原数据集中哪些特征的值作为缺失值。

    skip_blank_lines读取数据时是否需要跳过原数据集中的空白 行,默认为True

    parse_dates如果参数值为True,则尝试解析数据框的行索引; 如果参数为列表,则尝试解析对应的日期列;如果参数为嵌套列 表,则将某些列合并为日期列;如果参数为字典,则解析对应的 列(字典中的值),并生成新的字段名(字典中的键)。

    thousands指定原始数据集中的千分位符。

    comment指定注释符,在读取数据时,如果碰到行首指定的注释符,则跳过改行。

    encoding如果文件中含有中文,有时需要指定字符编码。

    下面举例说明:

    这里构造一个稍 微复杂点的数据集用于测试,数据存放在txt 中。

    #读取文本文件中的数据
    user_income = pd.read_table ('data.txt',sep = ',',parse_dates= { 'birthday':[ 0,1,2] },skiprows=2,skipfooter=3,comment='#',encoding='utf8',thousands='&')
    user_income

    代码说明:由于read_table函数在读取数 据时,默认将字段分隔符sep设置为Tab制表符,而原始数据集是用逗号 分割每一列,所以需要改变sep参数;parse_dates参数通过字典实现前三 列的日期解析,并合并为新字段birthdayskiprowsskipfooter参数分别 实现原数据集开头几行和末尾几行数据的跳过;由于数据部分的第四行 前面加了#号,因此通过comment参数指定跳过的特殊行;这里仅改变 字符编码参数encoding是不够的,还需要将原始的txt文件另存为UTF-8 格式;最后,对于收入一列,由于千分位符为&,因此为了保证数值型 数据的正常读入,需要设置thousands参数为&

    2、电子表格的读取

    pd.read_excel(io,sheetname=0,header=0,skiprows=None,skip_footer=0,
                  index_col=None,names=None,parse_cols-None,                    
                  parse_dates=False,na_values=None,thousands=None,convert_float=True)
    

    pd.read_excel参数介绍:

    io指定电子表格的具体路径。

    sheetname指定需要读取电子表格中的第几个Sheet,既可以传 递整数也可以传递具体的Sheet名称。

    header是否需要将数据集的第一行用作表头,默认为是需要 的。

    skiprows读取数据时,指定跳过的开始行数。

    skip_footer读取数据时,指定跳过的末尾行数。

    index_col指定哪些列用作数据框的行索引(标签)。

    names如果原数据集中没有字段,可以通过该参数在数据读取 时给数据框添加具体的表头。

    parse_cols指定需要解析的字段。

    parse_dates如果参数值为True,则尝试解析数据框的行索引; 如果参数为列表,则尝试解析对应的日期列;如果参数为嵌套列 表,则将某些列合并为日期列;如果参数为字典,则解析对应的 列(字典中的值),并生成新的字段名(字典中的键)。

    na_values指定原始数据中哪些特殊值代表了缺失值。

    thousands指定原始数据集中的千分位符。

    convert_float默认将所有的数值型字段转换为浮点型字段。

    converters通过字典的形式,指定某些列需要转换的形式。

    三、数据类型转换及描述统计

            内容主要介绍如何了解数据,例如读 入数据的规模如何、各个变量都属于什么数据类型、一些重要的统计指 标对应的值是多少、离散变量各唯一值的频次该如何统计等。下面以泰坦尼克号乘客信息为例:

    # 数据读取 
    sec_cars = pd.read_table(r'train.csv', sep = ',') 
    # 预览数据的前五行 
    sec_cars.head()

    如上代码中,head方法可以返回 数据集的开头5行;如果读者需要查看数据集的末尾5行,可以使用tail 方法。进一步,如果还想知道数据集有多少观测和多少变量,以及每个 变量都是什么数据类型,可以按如下代码得知:

    # 查看数据的行列数
    print('数据集的行列数:\n',sec_cars.shape)
    #查看数据集每个变量的数据类型
    print('各变量的数据类型:\n',sec_cars.dtypes)

     

    接下来,需要对数据做到心中有数,即通过基本的统计量(如最小 值、均值、中位数、最大值等)描述出数据的特征。关于数据的描述性 分析可以使用describe方法:

    # 数据的描述性统计 
    sec_cars.describe()

    通过describe方法,直接运算了数据框中所有数值 型变量的统计值,包括非缺失个数、平均值、标

    准差、最小值、下四分 位数、中位数、上四分位数和最大值。

    以上都是有关数据的统计描述,但并不能清晰地知道数据的形状分布,如数据是否有偏以及是否属

    于“尖峰厚尾”的特征,为了一次性统计 数值型变量的偏度和峰度,可以参考如下代码:

    #挑出所有数值型变量
    num_variables = sec_cars.columns[sec_cars.dtypes !='object'] [1:]#自定义函数,计算偏度和峰度
    def skew_kurt(x):
        skewness = x.skew ()
        kurtsis =x.kurt()
        #返回偏度值和峰度值
        return pd.Series( [skewness, kurtsis], index = [ 'Skew', 'Kurt'])
    #运用apply方法
    sec_cars[num_variables ].apply(func = skew_kurt,axis = 0)

    如上结果所示正是每个数值型变量的偏度和峰度,这三个变量都属 于右偏(因为偏度值均大于0),而且三个变量也是尖峰的(因为峰度 值也都大于0)。

    代码说明:columns方法用于返回数据集的所有变量 名,通过布尔索引和切片方法获得所有的数值型变量;在自定义函数 中,运用到了计算偏度的skew方法和计算峰度的kurt方法,然后将计算 结果组合到序列中;最后使用apply方法,该方法的目的就是对指定轴 (axis=0,即垂直方向的各列)进行统计运算(运算函数即自定义函 数)。

    以上的统计分析全都是针对数值型变量的,对于数据框中的字符型变量,该如何做统计描述

    呢?仍然可以使用describe方法,所不同的是,需要设置该方法中的

    include参数,具体代码如下:

    # 离散型变量的统计描述 
    sec_cars.describe(include = ['object'])

    对于离散型变量,运用describe方法只能得知哪个离散水平属于明 星”值。如果读者需要统计的是

    各个离散值的频次,甚至是对应的频率,该如何计算呢?这里直接给出如下代码(Sex为例):

    # 离散变量频次统计 
    Freq = sec_cars.Sex.value_counts() 
    Freq_ratio = Freq/sec_cars.shape[0] 
    Freq_df = pd.DataFrame({'Freq':Freq,'Freq_ratio':Freq_ratio}) 
    Freq_df.head()

    如果需要把行标签设置为数据框中的列,可以使用 reset_index方法,具体操作如下:

    # 将行索引重设为变量 
    Freq_df.reset_index(inplace = True) 
    Freq_df.head()

    reset_index方法的使用还是比较频繁的,它可以非常方便地将行标 签转换为数据框的变量。在如上代码中,将reset_index方法中的inplace参数设置为True,表示直接对原始数据集进行操作,响到原数据集的 变化,否则返回的只是变化预览,并不会改变原数据集。

    四、字符与日期数据的处理

    本节会介绍有关 日期型数据的处理,比方说,如何从日期型变量中取出年份、月份、星 期几等,如何计算两个日期间的时间差。

    下面不啰嗦,直接举例说明:数据集查看2

     

     下面演示一些常用的操作:

    #数据读入
    df = pd.read_excel('data.xlsx')
    #各变量数据类型
    df.dtypes
    #将出生日期变量转换为日期型
    df.出生日期 = pd.to_datetime (df.出生日期,format = '%Y /%m/%d')
    #将手机号转换为字符串
    df .电话号码 = df.电话号码.astype ( 'str')
    #新增年龄和工龄两列
    df [ '年龄'] = pd.datetime.today ().year - df.出生日期.dt.year
    df [ '工龄'] = pd.datetime.today ().year - df.工作时间.dt.year
    #取出邮箱的域名
    df [ '邮箱域名'] = df.邮箱.apply(func = lambda x : x.split ('@') [1])
    #将手机号中间四位隐藏起来
    df.电话号码 = df.电话号码.apply(func = lambda x : x.replace(x[3:7],'**** '))
    #去除邮箱变量
    df.drop([ '邮箱' ], axis = 1, inplace = True)
    df.head()

     常用的日期时间处理“方法”

    接下来,挑选几个日期处理 方法 用以举例说明:
    #常用日期处理方法
    dates = pd.to_datetime (pd.Series(['1989-8-18 13:14:55','1995-2-16']),format='%Y-%m-%d %H:%M:%S')
    print('返回日期值:\n ',dates.dt.date)
    print('返回季度:\n',dates.dt.quarter)
    print('返回几点钟:\n',dates.dt.hour)
    print('返回年中的天:\n',dates.dt.dayofyear)
    print ('返回年中的周:\n',dates.dt .weekofyear)
    #print('返回星期几的名称:\n',dates.dt.weekday_name)
    print('返回月份的天数: \n ',dates.dt.days_in_month)

    五、常用的数据清洗方法

           在数据处理过程中,一般都需要进行数据的清洗工作,如数据集是 否存在重复、是否存在缺失、数据是否具有完整性和一致性、数据中是 否存在异常值等。当发现数据中存在如上可能的问题时,都需要有针对 性地处理,本节将重点介绍如何识别和处理重复观测、缺失值和异常值。

    1、重复观测处理

    2、缺失值处理

    3、异常值处理

    六、数据子集的获取

           有时数据读入后并不是对整体数据进行分析,而是数据中的部分子 集,例如,对于地铁乘客量可能只关心某些时间段的流量、对于商品的 交易可能只需要分析某些颜色的价格变动、对于医疗诊断数据可能只对 某个年龄段的人群感兴趣等。所以,该如何根据特定的条件实现数据子 集的获取将是本节的主要内容。

    #构造数据集
    df1 = pd.DataFrame ( {'name':[ '张三','李四','王二','丁一','李五'],
    'gender':['男','女','女','女','男'],
    'age':[23,26,22,25,27]},columns = ['name' , 'gender' , 'age'])
    df1
    #取出数据集的中间三行{即所有女性),并且返回姓名和年龄两列
    #df1.iloc[1:4, [0,2]]
    #df1.loc[ 1 : 3,['name','age']]
    #df1.ix[1:3,[0.2]]

    如上结果所示,如果原始数据的行号与行标签(名称)一致, iloc、locix三种方法都可以取出满足条件的数据子集。所不同的是, iloc运用了索引的思想,故中间三行的表示必须用1:4,因为切片索引取 不到上限,同时,姓名和年龄两列也必须用数值索引表示;loc是指获 取行或列的标签(名称),由于该数据集的行标签与行号一致,所以 1:3就表示对应的3个行名称,而姓名和年龄两列的获取就不能使用数值 索引了,只能写入具体的变量名称;ix则混合了ilocloc的优点,如果 数据集的行标签与行号一致,则ix对观测行的筛选与loc的效果一样,但 是ix对变量名的筛选既可以使用对应的列号(如代码所示),也可以使 用具体的变量名称。

    # 将员工的姓名用作行标签 
    df2 = df1.set_index('name')
    df2 # 取出数据集的中间三行 df2.iloc[1:4,:] 
    df2.loc[['李四','王二','丁一'],:] 
    df2.ix[1:4,:]
    很显然,在实际的学习和工作中,观测行的筛选很少是通过写入具 体的行索引或行标签,而是对某些列做条件筛选,进而获得目标数据。 例如,在上面的df1数据集中,如何返回所有男性的姓名和年龄,代码 如下:
    # df1.iloc[df1.gender == '男',] 
    df1.loc[df1.gender == '男',['name','age']] 
    df1.ix[df1.gender == '男',['name','age']]

            综上所述,ix方法几乎可以实现所有情况中数据子集的获取,是 iloc和loc两种方法的优点合成体,而且对于行号与行名称一致的数据集 来说(如df1数据集),名称索引的优先级在位置索引之前(如本节第 一段代码中的df1.ix[1:3,[0,2]])。

    七、透视表功能

    如果这样的汇总过程不是在Excel中,而是在Python中,该如何实现呢?Pandas模块提供了实现透视表功能的pivot_table函数,该函数简单易用,与Excel的作思想完全一致,相信读者一定可以快速掌握函数 的用法及参数含义。接下来向读者介绍一下有关该函数的参数含义:

    pd.pivot_table(data,values=None,index=None,columns=None,
    aggfunc='mean', fill_value=None,margins=False,dropna=True, margins_name= 'Al1')
    

    data指定需要构造透视表的数据集。

    values指定需要拉入数值框的字段列表。

    index指定需要拉入行标签框的字段列表。

    columns指定需要拉入列标签框的字段列表。

    aggfunc指定数值的统计函数,默认为统计均值,也可以指定numpy模块中的其他统计函数。

    fill_value指定一个标量,用于填充缺失值。

    marginsbool类型参数,是否需要显示行或列的总计值,默认为False。

    dropnabool类型参数,是否需要删除整列为缺失的字段,默认为True

    margins_name指定行或列的总计名称,默认为All

    为了说明该函数的灵活功能,这里以上面的珠宝数据为例,重现 Excel制作成的透视表。首先来尝试一下单个分组变量的均值统计,具 体代码如下:

    # 数据读取 diamonds = pd.read_table(r'diamonds.csv', sep = ',') 
    # 单个分组变量的均值统计 
    pd.pivot_table(data = diamonds, index = 'color', values = 'price', margins = True,margins_name = '总计')

    如上结果所示就是基于单个分组变量color的汇总统计(price的均 值),返回结果属于Pandas模块中的序列类型,该结果与Excel形成的透 视表完全一致。接下来看看如何构造两个分组变量的列联表,代码如下 所示:

    #两个分组变量的列联表
    #导入numpy模块
    import numpy as np
    pd.pivot_table (data = diamonds,index m 'clarity', columns = 'cut ',values = 'carat',
    aggfunc - np.size,margins = True,margins_name - '总计')
    

    八、表之间的合并与连接

    Pandas模块同样提供了关于多表之间的合并和连接操作函数,分别 是concat函数和merge函数,首先介绍一下这两个函数的用法和重要参数 含义。

    (1)合并函数 concat
    pd.concat(objs, axis=0, join='outer', join_axes=None, ignore_index=False)
    

    objs指定需要合并的对象,可以是序列、数据框或面板数据构 成的列表。

    axis指定数据合并的轴,默认为0,表示合并多个数据的行,如 果为1,就表示合并多个数据的列。

    join指定合并的方式,默认为outer,表示合并所有数据,如果 改为inner,表示合并公共部分的数据。

    join_axes合并数据后,指定保留的数据轴。

    ignore_indexbool类型的参数,表示是否忽略原数据集的索引, 默认为False,如果设为True,就表示忽略原索引并生成新索引。

    keys为合并后的数据添加新索引,用于区分各个数据部分。

    #构造数据集df1和 df2
    df1 = pd.DataFrame ( { 'name' :[ '张三','李四','王二'], 'age' : [21,25,22],
    'gender" :['男','女·,'男']})
    df2 = pd.DataFrame ( { 'name' : [ '丁一', '赵五'],'age' :[23,22],'gender ' : [ '女', '女']})
    #数据集的纵向合并
    pd.concat ([df1, df2] , keys =['df1', 'df2 '])
    #并如果df2数据集中的“姓名变量为Name”
    df2 = pd.DataFrame ( { 'Name ' : [ '丁一','赵五'],'age ' : [23,22],'gender ' : ['女', '女'] )
    #数据集的纵向合并
    pd.concat([df1,df2])
    
    (2)连接函数 merge
    pd.merge(left, right, how='inner', on=None, left_on=None, right_on=None, left_index=False, right_index=False, sort=False)

    left指定需要连接的主表。

    right指定需要连接的辅表。

    how指定连接方式,默认为inner内连,还有其他选项,如左连 left、右连right和外连outer

    on指定连接两张表的共同字段。left_on:指定主表中需要连接的共同字段。

    right_on指定辅表中需要连接的共同字段。

    left_indexbool类型参数,是否将主表中的行索引用作表连接的 共同字段,默认为False

    right_indexbool类型参数,是否将辅表中的行索引用作表连接 的共同字段,默认为False

    sortbool类型参数,是否对连接后的数据按照共同字段排序, 默认为False

    suffixes如果数据连接的结果中存在重叠的变量名,则使用各自 的前缀进行区分。

    九、分组聚合操作

    df=pd.DataFrame({'A':['foo','bar','foo','bar','foo','bar','foo','foo'],'B':['one','one','two','three','two','two','one','three'],'C':np.random.randn(8),'D':np.random.randn(8)})
    df.groupby('A').sum()
    df.groupby(['A','B']).sum()

    展开全文
  • 安装pandas模块包,载入练习数据。 在pandas中,常用的载入函数是read_csv。除此之外还有read_excel和read_table,table可以读取txt。若是服务器相关的部署,则还会用到read_sql,直接访问数据库,但它必须配合...

    安装pandas模块包,载入练习数据。

    在pandas中,常用的载入函数是read_csv。除此之外还有read_excel和read_table,table可以读取txt。若是服务器相关的部署,则还会用到read_sql,直接访问数据库,但它必须配合mysql相关包。

    read_csv拥有诸多的参数,encoding是最常用的参数之一,它用来读取csv格式的编码。这里使用了gb2312,该编码常见于windows,如果报错,可以尝试utf-8。

    sep参数是分割符,有些csv文件用逗号分割列,有些是分号,有些是\t,这些都需要具体设置。header参数为是否使用表头作为列名。

    names参数可以为列设置额外的名字,比如csv中的表头是中文,但是在pandas中最好转换成英文。

    通过输出我们可以看到其表格的行与列数,但由于篇幅原因,显示中部分数据省略。我们可以通过调整展示的长度及宽度显示更多文件信息。

    因为数据集的数据比较多,如果我们只想浏览部分的话,可以使用head函数,显示头部的数据,默认5,也可以自由设置参数,如果是尾部数据则是tail。

    不设置head函数参数,输出结果如下:

    设置head函数参数值为7,结果输出如下:

    不设置tail函数参数,输出结果如下: 

    设置tail函数参数为6,输出结果如下: 

    检查是否有重复数据,其中positionId是职位ID,具备唯一性,我们通过此列进行重复数据检查。

    我们得到唯一值只有5031个,但根据表格共有6876个数据,我们需要将重复数据清除。

    使用drop_duplicates清除重复数据。

    drop_duplicates函数通过subset参数选择以哪个列为去重基准。keep参数则是保留方式,first是保留第一个,删除后余重复值,last还是删除前面,保留最后一个。duplicated函数功能类似,但它返回的是布尔值。

    接下来处理salary薪资数据。计算出薪资下限以及薪资上限。薪资内容没有特殊的规律,既有小写k,也有大K,还有k以上等用法,k以上只能上下限默认相同。

    这里需要用到pandas中的apply。它可以针对DataFrame中的一行或者一数据进行操作,允许使用自定义函数。

    定义一个cut_word函数,它查找「-」符号所在的位置,并且截取薪资范围开头至K之间的数字,也就是我们想要的薪资上限。

    apply将cut_word函数应用在salary列的所有行。

    对于k以上写法的数据,find函数会返回-1,如果按照原来的方式截取,是word[:-2],不是我们想要的结果,所以需要加一个if判断。

    因为python大小写敏感,我们用upper函数将k都转换为K,然后以K作为截取。

    输出bottomSalary及topSalary值。

    接下来进行平均薪资的求解,在求平均薪资前,我们需要将需要使用数据转换为int类型再进行运算。

    数据类型转换为数字,这里引入新的知识点,匿名函数lambda作为一次性函数。

    lambda x: * ,前面的lambda x:理解为输入,后面的星号区域则是针对输入的x进行运算。案例中,因为同时对top和bottom求平均值,所以需要加上x.bottomSalary和x.topSalary。word_cut的apply是针对Series,现在则是DataFrame。

    axis是apply中的参数,axis=0表示将函数用在行,axis=1则是列。输出下图结果。 

    据清理完成后,我们将想要分析的数据切选出,为后续的分析。

    这里依旧可以使用head、tail函数等设置参数查看开始和结尾的部分数据。

    下面对几个数据进行描述统计。

    value_counts是计数,统计所有非零元素的个数,以降序的方式输出Series。对city一列进行统计:

    对education一列进行统计:

    于薪资的统计,我们使用describe函数

    Describe函数能快速生成各类统计指标。薪资的平均数是17k,中位数是15k,最大薪资在75k 

    标准差在8.99k,有一定的波动性,大部分薪资在17±9k之间。

    一般分类数据用value_counts,数值数据用describe,这是最常用的两个统计函数。

     pandas自带绘图函数,它是以matplotlib包为基础封装,所以两者能够结合使用。 

    hist函数很方便的就绘制除出直方图。图表列出了薪资的分布,因为大部分薪资集中20k以下,为了更细的粒度。将直方图的宽距继续缩小。 

    数据分析的一大思想是细分维度,现在观察不同城市、不同学历对薪资的影响。箱线图是最佳的观测方式。 

    图表的标签出了问题,出现了白框,主要是图表默认用英文字体,而这里的都是中文,导致了冲突。所以需要改用matplotlib。 

    boxplot是我们调用的箱线图函数,column选择箱线图的数值,by是选择分类变量,figsize是尺寸。从图上我们看到,北京的薪资高于其他城市,尤其是中位数。上海和深圳稍次,广州甚至不如杭州。

    修改分类变量为education,得到学历对薪资的影响箱线图。

     

     上述两个研究均为单一的变量的分析,现在想知道北京和上海这两座城市,学历对薪资的影响。

    在by传递多个值,箱线图的刻度自动变成元组,也就达到了横向对比的作用。在pandas中,需要同时用到多个维度分析时,可以用groupby函数。它和SQL中的group by差不多,能将不同变量分组。

    上图是标准的用法,按city列,针对不同城市进行了分组。不过它并没有返回分组后的结果,只返回了内存地址。这时它只是一个对象,没有进行任何的计算,现在调用groupby的count方法。

    它返回的是不同城市的各列计数结果,因为没有NaN,每列结果都是相等的。现在它和value_counts等价。

    换成mean,计算出了不同城市的平均薪资。因为mean方法只针对数值,而各列中只有aveSalary是数值,于是返回了这个唯一结果。 

    groupby可以传递一组列表,这时得到一组层次化的Series。按城市和学历分组计算了平均薪资。

     

    后面再调用unstack方法,进行行列转置,这样看的就更清楚了。在不同城市中,博士学历最高的薪资在深圳,硕士学历最高的薪资在杭州。北京综合薪资最好。

     

    这次换成count,我们在groupby后面加一个avgSalary,说明只统计avgSalary的计数结果,不用混入相同数据。图上的结果很明确了,要求博士学历的岗位只有6个,所谓的平均薪资,也只取决于公司开出的价码,波动性很强,毕竟这只是招聘薪资,不代表真实的博士在职薪资。这也解释了上面几个图表的异常。

    接下来计算不同公司招聘的数据分析师数量,并且计算平均数。 

    这里使用了agg函数,同时传入count和mean方法,然后返回了不同公司的计数和平均值两个结果。所以前文的mean,count,其实都省略了agg。agg除了系统自带的几个函数,它也支持自定义函数。 

     

    上图用lambda函数,返回了不同公司中最高薪资和最低薪资的差值。agg是一个很方便的函数,它能针对分组后的列数据进行丰富多彩的计算。但是在pandas的分组计算中,它也不是最灵活的函数。

    下面想计算出不同城市,招聘数据分析师需求前5的公司,agg虽然能返回计数也能排序,但它返回的是所有结果,前五还需要手工计算。所以我们使用apply进行操作 

    自定义了函数topN,将传入的数据计数,并且从大到小返回前五的数据。然后以city聚合分组,因为求的是前5的公司,所以对companyShortName调用topN函数。

    同样的,想知道不同城市,各职位招聘数前五,也能直接调用topN。 

     

    agg和apply是不同的,虽然某些方法相近,比如求sum,count等,但是apply支持更细的粒度,它能按组进行复杂运算,将数据拆分合并,而agg则必须固定为列。

    运用group by,我们已经能随意组合不同维度。接下来配合group by作图。

    多重聚合在作图上面没有太大差异,行列数据转置不要混淆即可。 

     

    上述的图例我们都是用pandas封装过的方法作图,如果要进行更自由的可视化,直接调用matplotlib的函数会比较好,它和pandas及numpy是兼容的。plt已经在上文中调用并且命名。 

     

    上图将上海和北京的薪资数据以直方图的形式进行对比。因为北京和上海的分析师人数相差较远,所以无法直接对比,需要用destiny参数转化为密度。设置alpha透明度,它比箱线图更直观。

    另外一种分析思路是对数据进行深加工。我们将薪资设立出不同的level 

    cut的作用是分桶,它也是数据分析常用的一种方法,将不同数据划分出不同等级,也就是将数值型数据加工成分类数据,在机器学习的特征工程中应用比较多。

      

    lambda转换百分比,然后作堆积百分比柱形图(matplotlib好像没有直接调用的函数)。这里可以较为清晰的看到不同等级在不同地区的薪资占比。它比箱线图和直方图的好处在于,通过人工划分,具备业务含义。0~3是实习生的价位,3~6是刚毕业没有基础的新人,整理数据那种,6~10是有一定基础的,以此类推。  

    下面统计组标签一列的数据。

    str方法允许我们针对列中的元素,进行字符串相关的处理,这里的[1:-1]不再是DataFrame和Series的切片,而是对字符串截取,这里把[]都截取掉了。如果漏了str,就变成选取Series第二行至最后一行的数据。

     使用完str后,它返回的仍旧是Series,当我们想要再次用replace去除空格。还是需要添加str的。

    positionLables本身有空值,所以要删除,不然容易报错。再次用str.split方法,把元素中的标签按「,」拆分成列表。

    通过apply和value_counts函数统计标签数。因为各行元素已经转换成了列表,所以value_counts会逐行计算列表中的标签,apply函数将value_counts应用在行上,最后将结果组成一张新表。

    用unstack完成行列转换,看上去有点怪,因为它是统计所有标签在各个职位的出现次数,绝大多数肯定是NaN。

    将空值删除,并且重置为DataFrame,此时level_0为标签名,level_1为df_index的索引,也可以认为它对应着一个职位,0是该标签在职位中出现的次数。部分职位的标签可能出现多次,这里忽略它。reset_index可以还原索引,重新变为默认的整型索引。 

    最后用groupby计算出标签出现的次数。

      

    清洗掉引号,设置词云相关的参数。因为在jupyter中显示图片,所以需要额外的配置figsize,不然wide和height的配置无效。wordcloud也兼容pandas,所以直接将结果传入,然后显示图片,去除坐标。

      

    展开全文
  • 强大的数据处理模块Pandas,可以解决数据的预处理工作,如数据类型的转换、缺失值的处理、描述性统计分析和数据的汇总等一、序列与数据框的构造Pandas模块的核心操作对象为序列和数据框。序列指数据集中的一个字段,...
  • pandas数据合并、分组聚合及其使用

    千次阅读 2020-11-14 22:19:45
    一、pandas数据合并 ...join操作按照左边原则进行,左边有几行,结果就会有几行,列为join操作双方列的总和,在左边未出现的赋值为NaN import pandas as pd import numpy as np def myPd(): t1 = pd.DataFrame(.
  • 参考链接: Python | 使用Pandas进行数据分析 转载自http://mp.weixin.qq.com/s?__biz=MjM5NjEyMDI2MQ==&mid=2455947430&idx=1&sn=11da6ff57dbaeae9343e822ac8a2f3a7&chksm=b1787b0c860ff21a...
  • 第五章Python数据处理工具 ——Pandas

    千次阅读 2019-07-18 09:44:14
    本章将介绍强大的数据处理模块Pandas,该模块可以帮助数据分析师轻松地解决数据的预处理问题,如数据类型的转换、缺失值的处理、描述性统计分析、数据的汇总等。 通过本章内容的学习,读者将会掌握如下知识点,进而...
  • 数据分析师招聘数据清洗实战数据导入并...首先载入的数据在pandas中,常用的载入函数是read_csv。除此之外还有read_excel和read_table,table可以读取txt。若是服务器相关的部署,则还会用到read_sql,直接访问数据库,
  • 1.pandas预处理的常用操作 链接的文章已经讲解的相对比较清楚了,包括: (1)缺失值处理:dropna(),fillna() (2)离散化:cut(),qcut() (3)分组聚合:groupby() (4)数据透视表:pivot_table() (5)...
  • Python 基础.docx

    2020-02-16 12:11:39
    python pandas Python 基础.docx
  • 2021.1.15——露谷作物计算器的小改进前言目标excel表格![在这里插入图片描述](https://img-blog.csdnimg.cn/20210115215307240.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0...
  • 此系列为博雅数智举办的线上培训课程——python数据科学实践,为期两个月,本系列记录我在此课程中所学所思。 本节课总览: ...以【出版信息】列为例,可查看总共计数有600条出版社数据,有42..
  • 在常见的数据挖掘工作中,脏数据包括如下内容: 缺失值 异常值 不一致的值 重复数据及含有特殊符号(如#、¥、*)的数据 缺失值的处理分为删除存在缺失值的记录、对可能值进行插补和不处理。 异常值是指样本中的...
  • 全文基于《射雕英雄传》语料库,下面是读入数据的一个基于Pandas的通用操作框架。 1.文档相似度 计算两个词相似度的原理:简单的说,就是将每个词的向量在空间上进行余弦运算,当cos越接近0时候,两者越相似。词袋...
  • Python数据分析与挖掘实战总结

    千次阅读 2021-02-04 22:55:42
    from __future__ import print_function import pandas as pd catering_sale = '../data/catering_sale.xls' #餐饮数据,一列为日期,一列为销量 data = pd.read_excel(catering_sale, index_col = u'日期') #读取...
  • 「推荐度」3最高,1最低。 01 文件读写 文件的读写包括常见的txt、Excel、xml、二进制文件以及其他格式的数据文本,主要用于本地数据的读写。 1. open(name[, mode[, buffering]]) 类型:Python内置函数 描述:...
  • Python项目实践-客户流失预测

    千次阅读 热门讨论 2020-01-05 18:00:08
    2.2 导入相关库及数据 import numpy as np import pandas as pd import seaborn as sns import matplotlib.pyplot as plt %matplotlib inline # 显示全部特征 pd.set_option('display.max_columns', None) df = pd....
  • 「推荐度」3最高,1最低。 01 文件读写 文件的读写包括常见的txt、Excel、xml、二进制文件以及其他格式的数据文本,主要用于本地数据的读写。 1. open(name[, mode[, buffering]]) 类型:Python内置函数 描述:...
  • 列为x坐标,右列为y坐标。 代码创建了x和y之间的散点图,我需要一段代码来过度绘制一条最适合散点图中的数据的行,而且我没有一个内置的pylab函数对我有用。 from matplotlib import *from...
  • python内置函数

    千次阅读 2019-09-18 07:22:12
    」3最高,1最低。 01 文件读写 文件的读写包括常见的txt、Excel、xml、二进制文件以及其他格式的数据文本,主要用于本地数据的读写。 1. open(name[, mode[, buffering]]) 类型: Python内置函数 描述: Python...
  • 练习Python第四天

    2022-07-28 09:36:20
    shutil.rmtree("dir")#删除目录,目录可不为删除父目录并删除全部子目录及文件。(慎用!linux:rm -r) os.getcwd()#获取当前路径(linux:pwd) 列举目录内容 os.listdir("dir")#列出路径中的全部文件和文件夹(linux...
  • 」3最高,1最低。     01 文件读写   文件的读写包括常见的txt、Excel、xml、二进制文件以及其他格式的数据文本,主要用于本地数据的读写。     1. open(name[, mode[, ...
  • for j in range(8): shi.write(i + 1, j, S[j]) book.save(savepath)#保存 五、数据分析 在爬取完数据存到excel表中会做一些数据处理:绘制数据图(饼状图、折线图、直方图)、以一列对整表进行排序、只取数据的...
  • Python 当当网数据分析

    千次阅读 2021-12-06 18:02:07
    Python 当当网图书 关注CSDN博客:程志伟的博客 Python 3.7.6 (default, Jan 8 2020, 20:23:39) [MSC v.1916 64 bit (AMD64)] ...IPython 7.12.0 -- An enhanced Interactive ...import pandas as pd import re .

空空如也

空空如也

1 2 3 4 5 6
收藏数 113
精华内容 45
关键字:

pandas删除某列为空的行