zoukankan      html  css  js  c++  java
  • Pandas常用操作

    参考天池AI
    github博客传送门
    csdn博客传送门

    安装pandas
    通过命令提示符 pip install pandas
    或者通过第三方发放版 Anaconda 进行鼠标操作安装

    Numpy学习教程传送门

    https://blog.csdn.net/zhanghao3389/article/details/82791862

    Series 的创建

    import numpy as np, pandas as pd
    
    # 通过一维数组创建序列
    arr1 = np.arange(10)  # 创建一个0~9的numpy数组对象
    print(arr1)           # 打印这个数组
    print(type(arr1))   #打印这个数组的类型
    s1 = pd.Series(arr1) # 将数组转换为 Series
    print(s1)             # 打印出这个Series
    print(type(s1))       # 打印出这个Series的数据类型类型
    

    通过字典的方式创建序列

    dic1 = {'a': 10, 'b': 20, 'c': 30, 'd': 40, 'e': 50}  # 创建一个字典dic1
    print(dic1)           # 打印这个字典
    print(type(dic1))     # 打印这个字典的数据类型
    s2 = pd.Series(dic1)  # 将这个字典转换为Series
    print(s2)             # 打印转换后的Series
    print(type(s2))       #打印转化后的Series数据类型 
    

    DataFrame的创建

    数据框的创建主要有三种方式
    1.通过二维数组创建数据框

    arr2 = np.array(np.arange(12)).reshape(4, 3)  # 创建一个0~11的数组,然后reshape成4*3的矩阵
    print(arr2)               # 打印出这个矩阵
    print(type(arr2))         # 打印出这个矩阵的数据类型
    df1 = pd.DataFrame(arr2)  # 将这个矩阵转换为 DataFrame
    print(df1)                # 打印出转换后的DataFrame
    print(type(df1))          # 打印出这个DataFrame的数据类型
    

    2.通过字典的方式创建数据框
    (1)字典列表

    dic2 = {'a': [1, 2, 3, 4], 'b': [5, 6, 7, 8], 'c': [9, 10, 11, 12], 'd': [13, 14, 15, 16]}  # 创建一个字典
    print(dic2)        # 打印出这个字典的内容
    print(type(dic2))  # 打印出这个字典的数据类型
    
    df2 = pd.DataFrame(dic2)  # 将这个字典转换为DataFrame
    print(df2)                # 打印出转化后的DataFrame
    print(type(df2))          # 打印出这个DataFrame的数据类型
    

    (2)嵌套字典

    dic3 = {'one': {'a': 1, 'b': 2, 'c': 3, 'd': 4}, 'two': {'a': 5, 'b': 6, 'c': 7, 'd': 8},
            'three': {'a': 9, 'b': 10, 'c': 11, 'd': 12}}  # 创建了一个嵌套的字典
    print(dic3)        # 打印出这个嵌套的字典
    print(type(dic3))  # 打印出这个字典的数据类型
    
    df3 = pd.DataFrame(dic3)  # 将这个嵌套字典转换为DataFrame
    print(df3)                # 打印出转换后的DataFrame
    print(type(df3))          # 打印出这个DataFrame的数据类型
    

    3.通过数据框的方式创建数据框

    df4 = df3[['one', 'three']]  # 通过调用df3中的两列数据进行创建DataFrame
    print(df4)                   # 打印出这个调用df3中数据的DataFrame
    print(type(df4))             # 打印出这个DataFrame的数据类型
    
    s3 = df3['one']  # 通过调用df3中的一列数据进行创建DataFrame会创建出Series
    print(s3)        # 打印出这个Series
    print(type(s3))  # 打印出这个Series的数据类型
    

    通过索引值或索引标签获取数据

    import numpy as np, pandas as pd
    
    s4 = pd.Series(np.array([1, 1, 2, 3, 5, 8]))  # 创建一个Series数据
    print(s4)        # 打印出这个数据
    print(s4.index)  # 打印出这个数据的索引
    

    现在我们为序列设定一个自定义的索引值:

    s4.index = ['a', 'b', 'c', 'd', 'e', 'f']  # 手动修改s4这个数据的索引(index)
    print(s4)                             # 打印修改索引后的Series
    print('s4[3]:
    ', s4[3])              # 取出下标为 3 的数据
    print('s4[e]:
    ', s4['e'])            # 取出索引为 e 的数据
    print('s4[1,3,5]:
    ', s4[[1, 3, 5]])  # 取出下标为 1 3 5 的数据
    print("s4[['a','b','d','f']]:
    ", s4[['a', 'b', 'd', 'f']])  # 取出索引为 a b d f 的数据
    print('s4[:4]:
    ', s4[:4])            # 切片到下标为 4 的所有数据
    print("s4['c':]:
    ", s4['c':])        # 切片索引为 c 开始后面所有的数据
    print("s4['b':'e']:
    ", s4['b':'e'])  # 切片索引为 b 开始 e 结束(左闭右开)的所有数据
    

    自动化对齐
    如果有两个序列,需要对这两个序列进行算术运算,这时索引的存在就体现的它的价值了—自动化对齐.

    s5 = pd.Series(np.array([10, 15, 20, 30, 55, 80]), index=['a', 'b', 'c', 'd', 'e', 'f'])  # 创建一个Series并指定索引
    print(s5)       # 打印出这个Series
    
    s6 = pd.Series(np.array([12, 11, 13, 15, 14, 16]), index=['a', 'c', 'g', 'b', 'd', 'f'])  # 创建一个Series并指定索引
    print(s6)       # 打印出这个Series
    print(s5 + s6)  # 将两个Series进行相加操作
    print(s5 / s6)  # 将两个Series进行相除操作
    # 由于s5中没有对应的g索引,s6中没有对应的e索引,所以数据的运算会产生两个缺失值NaN。
    # 注意,这里的算术结果就实现了两个序列索引的自动对齐,而非简单的将两个序列加总或相除对于数据框的对齐,不仅仅是行索引的自动对齐,同时也会自动对齐列索引(变量名)
    

    利用pandas查询数据

    import pandas as pd
    
    # 可以通过布尔索引有针对的选取原数据的子集、指定行、指定列等。
    stu_dic = {'Age': [14, 13, 13, 14, 14, 12, 12, 15, 13, 12, 11, 14, 12, 15, 16, 12, 15, 11, 15],
               'Height': [69, 56.5, 65.3, 62.8, 63.5, 57.3, 59.8, 62.5, 62.5, 59, 51.3, 64.3, 56.3, 66.5, 72, 64.8, 67, 57.5, 66.5],
               'Name': ['Alfred', 'Alice', 'Barbara', 'Carol', 'Henry', 'James', 'Jane', 'Janet', 'Jeffrey', 'John',  'Joyce', 'Judy', 'Louise', 'Marry', 'Philip', 'Robert', 'Ronald', 'Thomas', 'Willam'],
               'Sex': ['M', 'F', 'F', 'F', 'M', 'M', 'F', 'F', 'M', 'M', 'F', 'F', 'F', 'F', 'M', 'M', 'M', 'M', 'M'],
               'Weight': [112.5, 84, 98, 102.5, 102.5, 83, 84.5, 112.5, 84, 99.5, 50.5, 90, 77, 112, 150, 128, 133, 85, 112]}
    # 创建了一个DataFrame数据框
    student = pd.DataFrame(stu_dic)
    

    查询数据的前5行或末尾5行 student.head() student.tail()

    print(student)                      # 打印这个数据框
    print('前五行:
    ', student.head())  # 查询这个数据框的前五行
    print('后五行:
    ', student.tail())  # 查询这个数据框的后五行
    

    查询指定的行

    print(student.loc[[0, 2, 4, 5, 7]])  # 这里的loc索引标签函数必须是中括号[]
    

    查询指定的列

    print(student[['Name', 'Height', 'Weight']].head())  # 如果多个列的话,必须使用双重中括号
    

    也可通过loc索引标签查询指定的列

    print(student.loc[:, ['Name', 'Height', 'Weight']].head)
    

    查询出所有12岁以上的女生信息

    print(student[(student['Sex'] == 'F') & (student['Age'] > 12)])
    

    查询出所有12岁以上的女生姓名,身高和体重

    print(student[(student['Sex'] == 'F') & (student['Age'] > 12)][['Name', 'Height', 'Weight']])
    

    利用pandas的DataFrames进行统计分析

    import numpy as np, pandas as pd
    
    np.random.seed(1234)
    d1 = pd.Series(2 * np.random.normal(size=100) + 3)
    d2 = np.random.f(2, 4, size=100)
    d3 = np.random.randint(1, 100, size=100)
    
    print('非空元素计算: ', d1.count())       # 非空元素计算
    print('最小值: ', d1.min())              # 最小值
    print('最大值: ', d1.max())              # 最大值
    print('最小值的位置: ', d1.idxmin())     # 最小值的位置,类似于R中的which.min函数
    print('最大值的位置: ', d1.idxmax())     # 最大值的位置,类似于R中的which.max函数
    print('10%分位数: ', d1.quantile(0.1))  # 10%分位数
    print('求和: ', d1.sum())               # 求和
    print('均值: ', d1.mean())              # 均值
    print('中位数: ', d1.median())          # 中位数
    print('众数: ', d1.mode())              # 众数
    print('方差: ', d1.var())               # 方差
    print('标准差: ', d1.std())             # 标准差
    print('平均绝对偏差: ', d1.mad())       # 平均绝对偏差
    print('偏度: ', d1.skew())             # 偏度
    print('峰度: ', d1.kurt())             # 峰度
    print('描述性统计指标: ', d1.describe())  # 一次性输出多个描述性统计指标
    # 必须注意的是,descirbe方法只能针对序列或数据框,一维数组是没有这个方法的
    

    这里自定义一个函数,将这些统计描述指标全部汇总到一起:

    def stats(x):
        return pd.Series([x.count(), x.min(), x.idxmin(), x.quantile(.25), x.median(), x.quantile(.75),x.mean(), x.max(), x.idxmax(), x.mad(), x.var(), x.std(), x.skew(), x.kurt()],index=['Count', 'Min', 'Whicn_Min', 'Q1', 'Median', 'Q3', 'Mean', 'Max','Which_Max', 'Mad', 'Var', 'Std', 'Skew', 'Kurt'])
    
    print(stats(d1))  # 打印统计后的指标
    

    将这个函数 应用到每一列中

    df = pd.DataFrame(np.array([d1,d2,d3]).T,columns=['x1','x2','x3'])
    print(df.head())
    print(df.apply(stats))
    

    连续变量的相关系数(corr)和协方差矩阵(cov)的求解

    print(df.corr())
    

    相关系数的计算可以调用pearson方法或kendell方法或spearman方法,默认使用pearson方法。

    print(df.corr('spearman'))
    

    关注某一个变量与其余变量的相关系数的话,可以使用corrwith,如下方只关心x1与其余变量的相关系数

    print(df.corrwith(df['x1']))
    

    数值型变量间的协方差矩阵

    print(df.cov())
    

    利用pandas实现SQL操作

    import pandas as pd, numpy as np
    
    # 原数据
    stu_dic = {'Age': [14, 13, 13, 14, 14, 12, 12, 15, 13, 12, 11, 14, 12, 15, 16, 12, 15, 11, 15],
               'Height': [69, 56.5, 65.3, 62.8, 63.5, 57.3, 59.8, 62.5, 62.5, 59, 51.3, 64.3, 56.3, 66.5, 72, 64.8, 67, 57.5, 66.5],
               'Name': ['Alfred', 'Alice', 'Barbara', 'Carol', 'Henry', 'James', 'Jane', 'Janet', 'Jeffrey', 'John', 'Joyce', 'Judy', 'Louise', 'Marry', 'Philip', 'Robert', 'Ronald', 'Thomas', 'Willam'],
               'Sex': ['M', 'F', 'F', 'F', 'M', 'M', 'F', 'F', 'M', 'M', 'F', 'F', 'F', 'F', 'M', 'M', 'M', 'M', 'M'],
               'Weight': [112.5, 84, 98, 102.5, 102.5, 83, 84.5, 112.5, 84, 99.5, 50.5, 90, 77, 112, 150, 128, 133, 85, 112]}
    student = pd.DataFrame(stu_dic)  # 将数据转换为DataFrame
    print(student)                   # 打印出这个数据
    

    添加新行或增加新列

    dic = {'Name': ['LiuShunxiang', 'Zhangshan'], 'Sex': ['M', 'F'], 'Age': [27, 23], 'Height': [165.7, 167.2],'Weight': [61, 63]}  # 需要增加的数据
    student2 = pd.DataFrame(dic)  # 增加数据
    print(student2)               # 打印出增加数据后的DataFrame
    

    现在将student2中的数据新增到student中 可以通过 concat函数实现

    student3 = pd.concat([student, student2])
    print(student3)
    

    注意 注意到了吗?在数据库中union必须要求两张表的列顺序一致,而这里concat函数可以自动对齐两个数据框的变量!

    新增列的话,其实在pandas中就更简单了,例如在student2中新增一列学生成绩

    print(pd.DataFrame(student2, columns=['Age', 'Weight', 'Name', 'Sex', 'Weight', 'Score']))
    

    删除数据框student2通过del命令实现,该命令可以删除Python的所有对象

    del student2  # 删除数据框 student2, 通过del命令可以删除Python的所有对象
    print(student2)
    

    删除指定的行

    print(student.drop([0, 1, 3, 6]))
    

    删除所有14岁以下的学生

    print(student['Age'] > 14)
    

    删除指定的列

    print(student.drop(['Height', 'Weight'], axis=1).head())  # axis默认为0选择行
    

    修改原始记录的 结合布尔索引和赋值的方法

    student3.loc[student3['Name'] == 'LiuShunxiang', 'Height'] = 173
    print(student3[student3['Name'] == 'LiuShunxiang'][['Name', 'Height']])
    

    有关数据查询部分
    聚合,排序和多表连接操作
    聚合:pandas模块中可以通过groupby()函数实现数据的聚合操作

    print(student.groupby('Sex').mean())
    

    如果不对原始数据作限制的话,聚合函数会自动选择数值型数据进行聚合计算。如果不想对年龄计算平均值的话,就需要剔除改变量

    print(student.drop('Age', axis=1).groupby('Sex').mean())
    

    groupby还可以使用多个分组变量,例如根本年龄和性别分组,计算身高与体重的平均值

    print(student.groupby(['Sex', 'Age']).mean())
    

    对每个分组计算多个统计量

    print(student.drop('Age', axis=1).groupby('Sex').agg([np.mean, np.median]))
    

    排序

    使用sort_index和sort_values实现序列和数据框的排序工作

    Data = pd.Series(np.array(np.random.randint(1, 20, 10)))
    print(Data)
    print(Data.sort_index())
    print(Data.sort_values(ascending=False))
    

    数据框中一般都是按值排序

    print(student.sort_values(by=['Age', 'Height']))
    

    多表连接

    多表之间的连接也是非常常见的数据库操作,连接分内连接和外连接,
    在数据库语言中通过join关键字实现,pandas我比较建议使用merger函数实现数据的各种连接操作。
    如下是构造一张学生的成绩表:

    dic2 = {'Name': ['Alfred', 'Alice', 'Barbara', 'Carol', 'Henry', 'Jeffrey', 'Judy', 'Philip', 'Robert', 'Willam'], 'Score': [88, 76, 89, 67, 79, 90, 92, 86, 73, 77]}
    score = pd.DataFrame(dic2)
    print(score)
    

    现在想把学生表student与学生成绩表score做一个关联

    stu_score1 = pd.merge(student, score, on='Name')
    print(stu_score1)
    

    注意,默认情况下,merge函数实现的是两个表之间的内连接,即返回两张表中共同部分的数据。

    可以通过how参数设置连接的方式,left为左连接;right为右连接;outer为外连接。

    stu_score2 = pd.merge(student, score, on='Name', how='left')
    print(stu_score2)
    

    利用pandas进行缺失值的处理

    三类方法 删除法 填补法 插值法

    删除法:当数据中的某个变量大部分值都是缺失值,可以考虑删除改变量;当缺失值是随机分布的,且缺失的数量并不是很多是,也可以删除这些缺失的观测。

    替补法:对于连续型变量,如果变量的分布近似或就是正态分布的话,可以用均值替代那些缺失值;如果变量是有偏的,可以使用中位数来代替那些缺失值;对于离散型变量,我们一般用众数去替换那些存在缺失的观测。

    插补法:插补法是基于蒙特卡洛模拟法,结合线性模型、广义线性模型、决策树等方法计算出来的预测值替换缺失值。

    import pandas as pd, numpy as np
    
    stu_score = {'Score': [88.0, 76.0, 89.0, 67.0, 79.0, None, None, None, 90.0, None, None, 92.0, None, None, 86.0, 73.0, None, None, 77.0]}
    stu_score2 = pd.DataFrame(stu_score)
    s = stu_score2['Score']
    print(s)
    # 结合sum函数和isnull函数来检测数据中含有多少缺失值
    print('缺失值个数:', sum(pd.isnull(s)))
    

    直接删除缺失值

    print('s.dropna():
    ', s.dropna())
    

    默认情况下,dropna会删除任何含有缺失值得行,我们再构造一个数据库试试

    df = pd.DataFrame([[1, 1, 2], [3, 5, np.nan], [13, 21, 34], [55, np.nan, 10], [np.nan, np.nan, np.nan], [np.nan, 1, 2]], columns=('x1', 'x2', 'x3'))
    print('df:
    ', df)
    print('df.dropna():
    ', df.dropna())
    

    使用一个常量来填补缺失值,可以使用fillna函数实现简单的填补工作

    print('df.fillna(0):
    ', df.fillna(0))  # 用 0 填补所有缺失值
    

    采用前项填充或后项填充

    print('method="ffill":
    ', df.fillna(method='ffill'))
    print('method="bfill":
    ', df.fillna(method='bfill'))
    

    使用常量填充不同的列

    print("{'x1': 1, 'x2': 2, 'x3': 3}:
    ", df.fillna({'x1': 1, 'x2': 2, 'x3': 3}))
    
    x1_median = df['x1'].median()
    x2_mean = df['x2'].mean()
    x3_mean = df['x3'].mean()
    
    print(x1_median)
    print(x2_mean)
    print(x3_mean)
    print(df.fillna({'x1': x1_median, 'x2': x2_mean, 'x3': x3_mean}))
    

    在使用填充法时,相对于常数填充或前项、后项填充,使用各列的众数、均值或中位数填充要更加合理一点,这也是工作中常用的一个快捷手段。

    利用pandas实现Excel的数据透视表功能

    import pandas as pd, numpy as np
    
    # pivot_table(data, values=None, index=None, columns=None, aggfunc='mean', fill_value=None, margins=False, dropna=True, margins_name='ALL')
    # data:需要进行数据透视表操作的数据框
    # values:指定需要聚合的字段
    # index:指定某些原始变量作为行索引
    # columns:指定哪些离散的分组变量
    # aggfunc:指定相应的聚合函数
    # fill_value:使用一个常数替代缺失值,默认不替换
    # margins:是否进行行或列的汇总,默认不汇总
    # dropna:默认所有观测为缺失的列
    # margins_name:默认行汇总或列汇总的名称为'All'
    
    stu_dic = {'Age': [14, 13, 13, 14, 14, 12, 12, 15, 13, 12, 11, 14, 12, 15, 16, 12, 15, 11, 15],
               'Height': [69, 56.5, 65.3, 62.8, 63.5, 57.3, 59.8, 62.5, 62.5, 59, 51.3, 64.3, 56.3, 66.5, 72, 64.8, 67, 57.5, 66.5],
               'Name': ['Alfred', 'Alice', 'Barbara', 'Carol', 'Henry', 'James', 'Jane', 'Janet', 'Jeffrey', 'John', 'Joyce', 'Judy', 'Louise', 'Marry', 'Philip', 'Robert', 'Ronald', 'Thomas', 'Willam'],
               'Sex': ['M', 'F', 'F', 'F', 'M', 'M', 'F', 'F', 'M', 'M', 'F', 'F', 'F', 'F', 'M', 'M', 'M', 'M', 'M'],
               'Weight': [112.5, 84, 98, 102.5, 102.5, 83, 84.5, 112.5, 84, 99.5, 50.5, 90, 77, 112, 150, 128, 133, 85, 112]}
    student = pd.DataFrame(stu_dic)
    

    对一个分组变量(Sex),一个数值变量(Height)作统计汇总

    Table1 = pd.pivot_table(student, values=['Height'], columns=['Sex'])
    print(Table1)
    

    对一个分组变量(Sex),两个数值变量(Height,Weight)做统计汇总

    Table2 = pd.pivot_table(student, values=['Height', 'Weight'], columns=['Sex'])
    print(Table2)
    

    对两个分组变量(Sex, Age), 两个数值变量(Height, Weight)做统计汇总

    Table3 = pd.pivot_table(student, values=['Height', 'Weight'], columns=['Sex', 'Age'])
    print(Table3)
    

    很显然这样的结果并不像Excel中预期的那样,该如何变成列联表的形式的?很简单,只需将结果进行非堆叠操作(unstack)即可

    Table4 = pd.pivot_table(student, values=['Height', 'Weight'], columns=['Sex', 'Age']).unstack()
    print(Table4)
    

    使用多个聚合函数

    Table5 = pd.pivot_table(student, values=['Height', 'Weight'], columns=['Sex'], aggfunc=[np.mean, np.median, np.std])
    print(Table5)
    

    有关更多数据透视表的操作,可参考http://python.jobbole.com/81212/

    多层索引的使用

    Series的层次化索引,索引是一个二维数组,相当于两个索引决定一个值
    有点类似于DataFrame的行索引和列索引

    import pandas as pd, numpy as np
    
    s = pd.Series(np.arange(1, 10), index=[['a', 'a', 'a', 'b', 'b', 'c', 'c', 'd', 'd'], [1, 2, 3, 1, 2, 3, 1, 2, 3]])
    print('s:
    ', s)
    print('s.index:
    ', s.index)
    
    # 选取外层索引为 a 的数据
    print("s['a']:
    ", s['a'])
    # 选取外层索引为 a 和内层索引为 1 的数据
    print("s['a', 1]:
    ", s['a', 1])
    # 选取外层索引为 a 和内层索引为 1,3的数据
    print("s['a'][[1, 3]]:
    ", s['a'][[1, 3]])
    # 层次化索引的切片,包括右端的索引
    print('s[["a", "c"]]:
    ', s[['a', 'c']])
    print('s["b":"d"]:
    ', s['b':'d'])
    # 通过unstack方法可以将Series变成一个DataFrame
    # 数据的类型以及数据的输出结构都变成了DataFrame,对于不存在的位置使用NaN填充
    print('s.unstack():
    ', s.unstack())
    

    DataFrame的层次化索引

    data = pd.DataFrame(np.random.randint(0, 150, size=(8,12)),columns=pd.MultiIndex.from_product([['模拟考', '正式考'],['数学', '语文', '英语', '物理', '化学', '生物']]),index=pd.MultiIndex.from_product([['期中', '期末'],['雷军', '李斌'],['测试一', '测试二']]))
    print('data:
    ', data)
    
    print('data["模拟考"]["语文","数学"]:
    ', data['模拟考'][['语文', '数学']])
    print("data.loc['期中', '雷军', '测试一']['模拟考', '数学']:
    ", data.loc['期中', '雷军', '测试一']['模拟考', '数学'])
    print("data.loc['期中', '雷军', '测试一']:
    ", data.loc['期中', '雷军', '测试一'])
    
    print("data['正式考']:
    ", data['正式考'])
    
  • 相关阅读:
    电影投票使用到index索引 isdigit range += format upper
    for循环删除列表里的内容 删除字典中的内容
    3.格式化输出 format 三种方法集合% f
    列表和字符串的转换及statswith,endswith的应用判断
    过滤器,使用到in for break
    sort排序及reverse反转的结合使用
    列表内的改动
    django 第五天 自定义标签 静态文件
    Mysql 基础 1
    django 第四天模板渲染
  • 原文地址:https://www.cnblogs.com/Mrzhang3389/p/9737616.html
Copyright © 2011-2022 走看看