Python - Pandas - 数据分析(2)

pandas数据分析

前言

Vue框架:从项目学Vue
OJ算法系列:神机百炼 - 算法详解
Linux操作系统:风后奇门 - linux
C++11:通天箓 - C++11

一行检查是否下载过Pandas:
pip list
一行下载:
pip install pandas

常用的21种统计方法

函数 功能
count 统计非空值个数
max 最大值
min 最小值
sum 求和
prod 乘积
cumsum 累和
cumprod 累乘
cummax 累积最大值
cummin 累积最小值
mean 平均值
std 标准差
var 方差
median 算数中位数
abs 绝对值
unique 唯一值列表
nunique 唯一值个数
value_counts 唯一值及其频数
skew 三阶偏度
kurt 四阶峰度
corr 相关系数矩阵
cov 协方差矩阵

describe():

describe将显示所有数值型特征的count(),mean(),std(),max&min()等
import pandas as pd
dataframe = pd.DataFrame({
    
    
	'a' : [1, 2, 3, 4, 5],
	'b' : [1.1, 1.2, 1.3, 1.4, 1.5],
	'c' : ['a', 'b', 'c', 'd', 'e']
})
dataframe.describe()

describe()

numeric_only:

  • 以上很多运算都只支持对int和float运算,其他类型需要对+等运算符重载
  • 若此类运算未对运算符 或 运算函数重载,则可能自动忽略,也可能报错终止
  • 大多情况上述统计学函数都搭配slice切片使用
# 均值
print(DataFrame.mean())

# 标准差
print(DataFrame.std())

# 累和
print(DataFrame.cumsum())

# 累乘
print(DataFrame.iloc[:, 0:2].cumprod())

cumsum

偏度skewness:

功能:

  • 用于描述数据的不对称性

含义:

  • skewness == 0:正态分布
  • skewness > 0:正偏差数值较大,数据右侧有很多极端值,整体分布右偏/正偏
  • skewness < 0:负偏差数值较大,数据左侧有很多极端值,整体分布左偏/负偏

计算公式:

  • s k e w n e s s = E [ ( x − E ( x ) ) / ( D ( x ) ) 3 ] skewness = E[(x - E(x)) / (\sqrt{D(x)})^3] skewness=E[(xE(x))/(D(x) )3]

演示:

import numpy as np
dataframe = pd.DataFrame({
    
    
    'id' : np.arange(10),
    #等比数列:起点、终点、个数,幂
    'value' : np.logspace(1, 10, 10, base = 2),
    #等差数列:起点、终点、个数
    'weight' : np.linspace(1, 10, 10)           
})
print(dataframe)
#skew()>0,value右侧异常值比较多
print(dataframe.skew())

skew

  • 画图看看:
#挑选数值型特征
num_feats = dataframe.dtypes[dataframe.dtypes != 'object'].index
import matplotlib.pyplot as plt
plt.figure(figsize = (8, 8))#8inch * 8inch
fig, ax = plt.subplots(2, 2) 
for row in range(2):
    for col in range(2):
        if row*2+col > 2 :
            continue
        data = dataframe[num_feats[row*2+col]]
        ax[row][col].plot(data.index, data.values)
        ax[row][col].set_title(f'{
      
      num_feats[row*2+col]}')
# 自动保持子图之间的正确间距。
fig.tight_layout()
plt.show()

skew

峰度值:

用途:

  • 描述某个变量所有取值分布形态陡缓程度的统计量,即数据分布的尖锐程度

数值:

  1. kurtosis == 0:陡缓程度和正态分布相同
  2. kurtosis > 0:比正态分布高峰陡峭,尖顶峰
  3. kurtosis < 0:比正态分布高峰平和,平顶峰

计算公式:

K u r t o s i s = E [ ( x − E ( x ) ) / ( D ( x ) ) 4 ] − 3 Kurtosis = E[(x - E(x)) / (\sqrt{D(x)})^4] - 3 Kurtosis=E[(xE(x))/(D(x) )4]3

演示:

  • 继续使用上组数据演示:
print(dataframe.kurt())

kurt

cov协方差

计算公式:

c o v ( X , Y ) = E [ ( X − E [ X ] ) ∗ ( Y − E [ Y ] ) ] , cov(X,Y)=E[ (X-E[X]) * (Y-E[Y]) ], cov(X,Y)=E[(XE[X])(YE[Y])],

  • E[X]代表变量X的期望。
  • 从直观上来看,协方差表示的是两个变量总体误差的期望。
  • 如果其中一个大于自身的期望值时另外一个也大于自身的期望值,两个变量之间的协方差就
    是正值;
  • 如果其中一个变量大于自身的期望值时另外一个却小于自身的期望值,那么两个变量之间的协方差就是负值。
  • 如果X与Y是统计独立的,那么二者之间的协方差就是0

数值:

  • corr()返回相关系数,介于[-1, 1]
  • |-1| 和 |1| 表示线性相关
  • 正负号表示正负相关

操作对象:

  • 对于含有n个特征值的DataFrame,两两之间计算协方差,构成n*n的矩阵
  • 协方差矩阵中对角线上是方差,非对角线是协方差

演示:

  • 继续使用以上数据:
dataframe.cov()

cov

扫描二维码关注公众号,回复: 15463292 查看本文章

corr相关系数:

计算公式:

  • 基于cov协方差
    ρ X Y = C o v ( X , Y ) / [ D ( X ) ] [ D ( Y ) ] ρXY = Cov(X,Y) / \sqrt{[D(X)]} \sqrt{[D(Y)}] ρXY=Cov(X,Y)/[D(X)] [D(Y) ]

数值:

  • corr()计算介于[-1, 1]的相关系数
  • |-1| 和 |1| 表示线性相关
  • 正负号表示正负相关

操作对象:

  • 对于含有n个特征值的DataFrame,两两之间计算相关系数,构成n*n的矩阵
  • 相关系数矩阵中对角线上永远是1

演示:

  • 继续使用上述数据:
dataframe.corr()

corr

常用的5种数据处理函数:

map:

  • 示意图:
    map

功能:

  • 依据给定的函数 / 字典,将DataFrame / Series中一列内每个值转化为其他数值

字典map:

  • 为DataFrame / Series .map()方法,传递一个字典
#转型字典
gendermap = {
    
    'F' : 0, 'M' : 1}

#数据
dataframe = pd.DataFrame({
    
    
    "name":['Jack', 'Alice', 'Lily', 'Mshis', 'Gdli', 'Agosh', 'Filu', 'Mack', 'Lucy', 'Pony'],
    "gender":['F', 'M', 'F', 'F', 'M', 'F', 'M', 'M', 'F', 'F'],
    "age":np.random.randint(15,50,10),
    "salary":np.random.randint(5,50,10),
    })

#map方法
dataframe['gender'] = dataframe['gender'].map(gendermap)
print(dataframe)

dictionary_map

函数map:

  • 为DataFrame / Series 的.map()传递进入一个函数指针
dataframe = pd.DataFrame({
    
    
    "name":['Jack', 'Alice', 'Lily', 'Mshis', 'Gdli', 'Agosh', 'Filu', 'Mack', 'Lucy', 'Pony'],
    "gender":['F', 'M', 'F', 'F', 'M', 'F', 'M', 'M', 'F', 'F'],
    "age":np.random.randint(15,50,10),
    "salary":np.random.randint(5,50,10),
    })
print(dataframe)
print('*'*40)

#转型函数
def gender_map(x) :
    gender = 0 if x == 'F' else 1
    return gender

dataframe['gender'] = dataframe['gender'].map(gender_map)

print(dataframe)

function_map

apply:

功能:

  • 遍历整个Series 和 DataFrame,对每个元素运行指定的函数,可以是自定义函数,也可以是上述的21种内置函数等等

apply匿名lambda:

df=pd.DataFrame({
    
    
    "name":['Jack', 'Alice', 'Lily', 'Mshis', 'Gdli', 'Agosh', 'Filu', 'Mack', 'Lucy', 'Pony'],
    "gender":['F', 'M', 'F', 'F', 'M', 'F', 'M', 'M', 'F', 'F'],
    "age":np.random.randint(15,50,10),
    "salary":np.random.randint(5,50,10),
    })

print(df)
print('*'*40)
print(df[['age', 'salary']].apply(lambda x: x*2))

apply内置函数

  • 确定可以执行内置函数的是哪些列
#传入的函数也可以是pandas和python内置函数
print(df[['age', 'salary']].apply(max))
print('*'*30)
print(df[['age', 'salary']].apply(np.mean))

apply内置函数

apply自己的函数:

#按值遍历调用
def apply_func(row):
    a = row['name']
    b = row['gender']
    c = row['age']
    return f'name:{
      
      a},gender:{
      
      b}, age:{
      
      c}'

#原地修改,增加一列all
df["all"] = df.apply(lambda row:apply_func(row), axis = 1)
#axis = 1,每次row为dataframe内的一行
print(df)

apply个人函数

groupy()

  • 功能同于Mysql中的groupby(),by参数可以传递入多个特征值
  • 传递入多个特征值时,分组是多个特征的排列组合,见下面的dfc.groupby(by=[‘gender’,‘age’])

不必having:

  • groupby()之后的操作都是针对每一组内部
import numpy as np
dfc=pd.DataFrame({
    
    
    "name":['Jack', 'Alice', 'Lily', 'Mshis', 'Gdli', 'Agosh', 'Filu', 'Mack', 'Lucy', 'Pony'],
    "gender":['F', 'M', 'F', 'F', 'M', 'F', 'M', 'M', 'F', 'F'],
    "age":np.random.randint(25,28,10),
    "salary":np.random.randint(5,50,10),
    })

#划分成组后求对应组的和结果
print(dfc.groupby(by='gender').sum())
print("*"*25)
# groupby查传入的可以时多个属性
print(dfc.groupby(by=['gender','age']).sum())

groupby()

groupby + apply:

  • apply()传入参数:
    1. lambda
    2. 内置func()
    3. 个人所写函数
  • apply对象:
    经过groupby()之后的多个小组,也就是子DataFrame

自定义排序:

  • 对于每个子DataFrame执行sort_values()即可
df=pd.DataFrame({
    
    
    "name":['Jack', 'Alice', 'Lily', 'Mshis', 'Gdli', 'Agosh', 'Filu', 'Mack', 'Lucy', 'Pony'],
    "gender":['F', 'M', 'F', 'F', 'M', 'F', 'M', 'M', 'F', 'F'],
    "age":np.random.randint(25,28,10),
    "salary":np.random.randint(5,50,10),
    })
print(df)
print('*'*40)

#此处的x也是一个dataframe
def group_staff_salary(x):
    df1 = x.sort_values(by = 'salary',ascending=True)
#ascending = True为从大到小的顺序,默认倒序
    return df1

df.groupby('gender',as_index=True).apply(group_staff_salary)

groupby + apply = order

获取每组最值:

  • 限制每个子DataFrame返回对象即可
#只看每组最高工资:
df=pd.DataFrame({
    
    
    "name":['Jack', 'Alice', 'Lily', 'Mshis', 'Gdli', 'Agosh', 'Filu', 'Mack', 'Lucy', 'Pony'],
    "gender":['F', 'M', 'F', 'F', 'M', 'F', 'M', 'M', 'F', 'F'],
    "age":np.random.randint(25,28,10),
    "salary":np.random.randint(5,50,10),
    })
print(df)
print("*"*40)

#此处的x也是一个dataframe
def group_staff_salary(x):
    df1 = x.sort_values(by = 'salary',ascending=True)
    return df1.iloc[-1, :]

df.groupby('gender',as_index=True).apply(group_staff_salary)
  • 查询到男女两方最高工资者信息:
    groupby + apply = max

agg:

功能:

  • 同时为一组数据指定多个执行函数

字典指定内置函数:

  • 字典的key是DataFrame的特征,字典的value是要对特征值执行的函数
  • 要对字典执行的函数很多时,可以传递数组
# 1:字典:key为列,val为操作函数
df=pd.DataFrame({
    
    
    "name":['Jack', 'Alice', 'Lily', 'Mshis', 'Gdli', 'Agosh', 'Filu', 'Mack', 'Lucy', 'Pony'],
    "gender":['F', 'M', 'F', 'F', 'M', 'F', 'M', 'M', 'F', 'F'],
    "age":np.random.randint(25,28,10),
    "salary":np.random.randint(5,50,10),
    })


df.agg({
    
    'age':['max'], 'salary':['mean', 'std']})
  • value作为行Index,key作为列Index
    字典指定agg

groupby + agg:

  • agg内许多函数的操作对象是groupby之后的子DataFrame的所有列:
df.groupby('gender').agg(['max', 'min', 'median'])
  • group作行Index,agg内函数作列index:
    groupby  + agg

lambda匿名函数:

  • agg内参数也可以是lambda表达式
df.groupby(['gender']).agg(lambda x: x.mean()-x.min())
  • groupby的特征值作为行Index,非by的特征值作为列Index
    groupby + agg + lambda

lambda匿名函数数组:

  • agg()内参数也可以是lambda表达式数组
df.groupby(['gender']).agg([lambda x: x.max()-x.min(), lambda x: x.mean()-x.min()])
  • 行Index为by的特征,列Index为lambda函数名
    groupby + agg + lambda

常用的两种文件操作:

读写csv文件:

读csv:

pd.read_csv('./test.csv')

写csv:

df.to_csv('./test.csv',index=False)
#不写行名

读写excel文件:

读excel:

pd.read_excel('./test.xlsx')

写excel:

df.to_excel('./test.xlsx',index=True)
#写行名

猜你喜欢

转载自blog.csdn.net/buptsd/article/details/129423974