使用Pandas 进行数据分析

目录

文章来自 20000字!一文学会Python数据分析

1 什么是Pandas?

2 Pandas数据类型

Series

DataFrame

3 Pandas数据查看

按列选取

按行选取

指定行列

4 Pandas条件查询

5 Pandas数学计算

聚合计算

按行、列聚合计算

agg函数

apply、applymap、map函数

6 Pandas合并连接

追加(Append)

合并(Concat)

连接(Merge)

数据连接 1 (pd.merge)

数据连接 2 (pd.merge)

7 Pandas分组聚合


文章来自 20000字!一文学会Python数据分析


1 什么是Pandas?

Pandas是一个开源的Python库,主要用于数据分析、数据处理、数据可视化。

Pandas作为Python数据分析的核心包,提供了大量的数据分析函数,包括数据处理、数据抽取、数据集成、数据计算等基本的数据分析手段。

Pandas的名称来自于面板数据(panel data)和python数据分析(data analysis)的简称。

千万记得Pandas不是咱们的国宝大熊猫的复数形式!!!(尽管这一强调极有可能适得其反,但还是忍不住贴一张panda的图)

2 Pandas数据类型

Pandas 有两种自己独有的基本数据结构。需要注意的是,它固然有着两种数据结构,因为它依然是 Python 的一个库,所以 Python 中有的数据类型在这里依然适用。我们分别看一下这两种数据结构:

Series

Series:一维数组。该结构能够放置各种数据类型,比如字符、整数、浮点数等

我们先引入pandas包,这里有一个约定成俗的写法import pandas as pd 将pandas引入,并命其别名为pd

接着将列表[2,3,5,7,11]放到pd.Series()里面

import pandas as pd
s = pd.Series([2,3,5,7,11],name = 'A')
s
0     2
1     3
2     5
3     7
4    11
Name: A, dtype: int64

Time- Series:以时间为索引的Series

同样的,将列['2024-01-01 00:00:00', '2024-01-01 03:00:00','2024-01-01 06:00:00'] 放到pd.DatetimeIndex()里面

dts1 = pd.DatetimeIndex(['2024-01-01 00:00:00', '2024-01-01 03:00:00','2024-01-01 06:00:00'])
dts1
DatetimeIndex(['2024-01-01 00:00:00', '2024-01-01 03:00:00',
               '2024-01-01 06:00:00'],
              dtype='datetime64[ns]', freq=None)

还有另外一种写法pd.date_range 可以按一定的频率生成时间序列

dts2 = pd.date_range(start='2024-01-01', periods=6, freq='3H')
dts2
DatetimeIndex(['2024-01-01 00:00:00', '2024-01-01 03:00:00',
               '2024-01-01 06:00:00', '2024-01-01 09:00:00',
               '2024-01-01 12:00:00', '2024-01-01 15:00:00'],
              dtype='datetime64[ns]', freq='3H')
dts3 = pd.date_range('2024-01-01', periods=6, freq='d')
dts3
DatetimeIndex(['2024-01-01', '2024-01-02', '2024-01-03', '2024-01-04',
               '2024-01-05', '2024-01-06'],
              dtype='datetime64[ns]', freq='D')

DataFrame

DataFrame:二维的表格型数据结构,可以理解为Series的容器,通俗地说,就是可以把Series放到DataFrame里面。

它是一种二维表格型数据的结构,既有行索引,也有列索引。行索引是 index,列索引是 columns。类似于初中数学里,在二维平面里用坐标轴来定位平面中的点。

注意,DataFrame又是Pandas的核心!接下来的内容基本上以DataFrame为主

先来看看如何创建DataFrame,上面说过Series也好,DataFrame也罢,本质上都是容器。

千万别被”容器“这个词吓住了,通俗来说,就是里面可以放东西的东西。

从字典创建DataFrame

相当于给里面放dict:先创建一个字典d,再把d放进了DataFrame里命名为df

d = {'A': [1, 2, 3], 
     'B': [4, 5, 6],
     'C': [7, 8, 9]}
df = pd.DataFrame(data = d)
df
ABC
0147
1258
2369

从列表创建DataFrame

先创建了一个列表d,再把d放进了DataFrame里命名为df1

d = [[4, 7, 10],[5, 8, 11],[6, 9, 12]]
df1 = pd.DataFrame(
    data = d,
    index=['a', 'b', 'c'],
    columns=['A', 'B', 'C'])
df1
ABC
a4710
b5811
c6912

从数组创建DataFrame

数组(array)对你来说可能是一个新概念,在Python里面,创建数组需要引入一个类似于Pandas的库,叫做Numpy。与前面引入Pandas类似,我们用 import numpy as np来引入numpy,命其别名为np。

同样的,先创建一个数组d,再把d放进了DataFrame里命名为df2

import numpy as np
d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
df2 = pd.DataFrame(data = d,
                   index=['a', 'b', 'c'],
                   columns=['A', 'B', 'C'])
df2
ABC
a123
b456
c789

以上,我们用了不同的方式来创建DataFrame,接下来,我们看看创建好后,如何查看数据


3 Pandas数据查看

这里我们创建一个DataFrame命名为df

import numpy as np
import pandas as pd
d =  np.array([[81, 28, 24, 25, 96],
       [ 8, 35, 56, 98, 39],
       [13, 39, 55, 36,  3],
       [70, 54, 69, 48, 12],
       [63, 80, 97, 25, 70]])
df = pd.DataFrame(data = d,
                  columns=list('abcde'))
df
abcde
08128242596
1835569839
2133955363
37054694812
46380972570

查看前2行

df.head(2)
abcde
08128242596
1835569839

查看后2行

df.tail(2)
abcde
37054694812
46380972570

查看随机2行

df.sample(2)
abcde
1835569839
37054694812

按列选取

单列选取,我们有3种方式可以实现

第一种,直接在[]里面写上要筛选的列名

df['a']
0    81
1     8
2    13
3    70
4    63
Name: a, dtype: int64

第二种,在.iloc[]里的逗号前面写上要筛选的行索引,在.iloc[]里的逗号后面写上要删选的列索引。其中写:代表所有,写0:3代表从索引0到2

df.iloc[0:3,0]
0    81
1     8
2    13
Name: a, dtype: int64

第三种,直接.后面写上列名

df.a
0    81
1     8
2    13
3    70
4    63
Name: a, dtype: int64

同样的,选择多列常见的也有3种方式:

第一种,直接在[]里面写上要筛选的列名组成的列表['a','c','d']

df[['a','c','d']]
acd
0812425
185698
2135536
3706948
4639725

第二种,在.iloc[]里面行索引位置写选取所有行,列索引位置写上要筛选的列索引组成的列表[0,2,3]

df.iloc[:,[0,2,3]]
acd
0812425
185698
2135536
3706948
4639725

第三种,在.loc[]里面的行索引位置写来选取所有行,在列索引位置写上要筛选的列索引组成的列表['a','c','d']

df.loc[:,['a','c','d']]
acd
0812425
185698
2135536
3706948
4639725

按行选取

直接选取第一行

df[0:1]
abcde
08128242596

loc选取第一行

df.loc[0:0]
abcde
08128242596

选取任意多行

df.iloc[[1,3],]
abcde
1835569839
37054694812

选取连续多行

df.iloc[1:4,:]
abcde
1835569839
2133955363
37054694812

指定行列

指定行列值

df.iat[2,2] # 根据行列索引
55
df.at[2,'c'] # 根据行列名称
55

指定行列区域

df.iloc[[2,3],[1,4]]
be
2393
35412

以上是关于如何查看一个DataFrame里的数据,包括用[]ilociat等方式选取数据,接下来我们来看如何用条件表达式来筛选数据:

4 Pandas条件查询

在pandas中,可以使用条件筛选来选择满足特定条件的数据

import pandas as pd
d =  np.array([[81, 28, 24, 25, 96],
       [ 8, 35, 56, 98, 39],
       [13, 39, 55, 36,  3],
       [70, 54, 69, 48, 12],
       [63, 80, 97, 25, 70]])
df = pd.DataFrame(data = d,
                  columns=list('abcde'))
df
abcde
08128242596
1835569839
2133955363
37054694812
46380972570
# 单一条件
df[df['a']>60]
df.loc[df['a']>60]
abcde
08128242596
37054694812
46380972570
# 单一条件&多列
df.loc[(df['a']>60) ,['a','b','d']]
abd
0812825
3705448
4638025
# 多条件
df[(df['a']>60) & (df['b']>60)]
abcde
46380972570
# 多条件 筛选行 & 指定列筛选列
df.loc[(df['a']>60) & (df['b']>60) ,['a','b','d']]
abd
4638025

以上是使用条件筛选来选取数据 ,接下来我们来看如何对数据进行数学计算

5 Pandas数学计算

import pandas as pd
d =  np.array([[81, 28, 24, 25, 96],
       [ 8, 35, 56, 98, 39],
       [13, 39, 55, 36,  3],
       [70, 54, 69, 48, 12],
       [63, 80, 97, 25, 70]])
df = pd.DataFrame(data = d,
                  columns=list('abcde'))
df
abcde
08128242596
1835569839
2133955363
37054694812
46380972570

聚合计算

聚合计算是指对数据进行汇总和统计的操作。常用的聚合计算方法包括计算均值、求和、最大值、最小值、计数等。

df['a'].mean()
47.0
df['a'].sum()
235
df['a'].max()
81
df['a'].min()
8
df['a'].count()
5
df['a'].median() # 中位数
63.0
df['a'].var() #方差
1154.5
df['a'].skew() # 偏度
-0.45733193928530436
df['a'].kurt() # 峰度
-2.9999915595685325
df['a'].cumsum() # 累计求和
0     81
1     89
2    102
3    172
4    235
Name: a, dtype: int64
df['a'].cumprod() # 累计求积
0          81
1         648
2        8424
3      589680
4    37149840
Name: a, dtype: int64
df['a'].diff() # 差分
0     NaN
1   -73.0
2     5.0
3    57.0
4    -7.0
Name: a, dtype: float64
df['a'].mad() # 平均绝对偏差
29.2

按行、列聚合计算

df.sum(axis=0)  # 按列求和汇总到最后一行
a    235
b    236
c    301
d    232
e    220
dtype: int64
df.sum(axis=1)  # 按行求和汇总到最后一列 
0    254
1    236
2    146
3    253
4    335
dtype: int64
df.describe() # 描述性统计
abcde
count5.0000005.0000005.0000005.0000005.000000
mean47.00000047.20000060.20000046.40000044.000000
std33.97793420.65671826.39507530.36939239.083244
min8.00000028.00000024.00000025.0000003.000000
25%13.00000035.00000055.00000025.00000012.000000
50%63.00000039.00000056.00000036.00000039.000000
75%70.00000054.00000069.00000048.00000070.000000
max81.00000080.00000097.00000098.00000096.000000

agg函数

对整个DataFrame批量使用多个聚合函数

df.agg(['sum', 'mean','max','min','median'])
abcde
sum235.0236.0301.0232.0220.0
mean47.047.260.246.444.0
max81.080.097.098.096.0
min8.028.024.025.03.0
median63.039.056.036.039.0

对DataFramed的某些列应用不同的聚合函数

df.agg({'a':['max','min'],'b':['sum','mean'],'c':['median']})
abc
max81.0NaNNaN
min8.0NaNNaN
sumNaN236.0NaN
meanNaN47.2NaN
medianNaNNaN56.0

apply、applymap、map函数

在Python中如果想要对数据使用函数,可以借助apply(),applymap(),map()对数据进行转换,括号里面可以是直接函数式,或者自定义函数(def)或者匿名函数(lambad)

1、当我们要对数据框(DataFrame)的数据进行按行或按列操作时用apply()

df.apply(lambda x :x.max()-x.min(),axis=1)
#axis=1,表示按行对数据进行操作
#从下面的结果可以看出,我们使用了apply函数之后,系统自动按行找最大值和最小值计算,每一行输出一个值
0    72
1    90
2    52
3    58
4    72
dtype: int64
df.apply(lambda x :x.max()-x.min(),axis=0)
#默认参数axis=0,表示按列对数据进行操作
#从下面的结果可以看出,我们使用了apply函数之后,系统自动按列找最大值和最小值计算,每一列输出一个值
a    73
b    52
c    73
d    73
e    93
dtype: int64

2、当我们要对数据框(DataFrame)的每一个数据进行操作时用applymap(),返回结果是DataFrame格式

df.applymap(lambda x : 1 if x>60 else 0)
#从下面的结果可以看出,我们使用了applymap函数之后,
#系统自动对每一个数据进行判断,判断之后输出结果
abcde
010001
100010
200000
310100
411101

3、当我们要对Series的每一个数据进行操作时用map()

df['a'].map(lambda x : 1 if x>60 else 0)
0    1
1    0
2    0
3    1
4    1
Name: a, dtype: int64

总结:

apply() 函数可以在DataFrame或Series上应用自定义函数,可以在行或列上进行操作。

applymap() 函数只适用于DataFrame,可以在每个元素上应用自定义函数。

map() 函数只适用于Series,用于将每个元素映射到另一个值。

以上是数学运算部分,包括聚合计算、批量应用聚合函数,以及对Series和DataFrame进行批量映射,接下来我们来看如何对数据进行合并拼接

6 Pandas合并连接

在pandas中,有多种方法可以合并和拼接数据。常见的方法包括append()concat()merge()

追加(Append)

append()函数用于将一个DataFrame或Series对象追加到另一个DataFrame中。

import pandas as pd
df1 = pd.DataFrame({'A': ['a', 'b'],
                   'B': [1, 2]})
df1
AB
0a1
1b2
df2 = pd.DataFrame({'A': [ 'b', 'c','d'],
                    'B': [2, 3, 4]})
df2
AB
0b2
1c3
2d4
df1.append(df2,ignore_index=True) 
AB
0a1
1b2
2b2
3c3
4d4

合并(Concat)

concat()函数用于沿指定轴将多个对象(比如Series、DataFrame)堆叠在一起。可以沿行或列方向进行拼接。

先看一个上下堆叠的例子

df1 = pd.DataFrame({'A': ['a', 'b'],
                   'B': [1, 2]})
df1
AB
0a1
1b2
df2 = pd.DataFrame({'A': [ 'b', 'c','d'],
                    'B': [2, 3, 4]})
df2
AB
0b2
1c3
2d4
pd.concat([df1,df2],axis =0) # 上下拼接
AB
0a1
1b2
0b2
1c3
2d4

再看一个左右堆叠的例子

df1 = pd.DataFrame({'A': ['a', 'b']})
df1
A
0a
1b
df2 = pd.DataFrame({'B': [1, 2],
                    'C': [2, 4]})
df2
BC
012
124
pd.concat([df1,df2],axis =1) # 左右拼接
ABC
0a12
1b24

连接(Merge)

merge()函数用于根据一个或多个键将两个DataFrame的行连接起来。类似于SQL中的JOIN操作。

数据连接 1 (pd.merge)

先看一下 inner 和 outer连接

df1 = pd.DataFrame({'A': ['a', 'b', 'c'],
                   'B': [1, 2, 3]})
df1
AB
0a1
1b2
2c3
df2 = pd.DataFrame({'A': [ 'b', 'c','d'],
                    'B': [2, 3, 4]})
df2
AB
0b2
1c3
2d4
pd.merge(df1,df2,how = 'inner')
AB
0b2
1c3
pd.merge(df1,df2,how = 'outer')
AB
0a1
1b2
2c3
3d4
数据连接 2 (pd.merge)

再看左右链接的例子:

df1 = pd.DataFrame({'A': ['a', 'b', 'c'],
                   'B': [1, 2, 3]})
df1
AB
0a1
1b2
2c3
df2 = pd.DataFrame({'A': [ 'b', 'c','d'],
                    'C': [2, 3, 4]})
df2
AC
0b2
1c3
2d4
pd.merge(df1,df2,how = 'left',on = "A")  # 左连接
ABC
0a1NaN
1b22.0
2c33.0
pd.merge(df1,df2,how = 'right',on = "A") # 右连接
ABC
0b2.02
1c3.03
2dNaN4
pd.merge(df1,df2,how = 'inner',on = "A") # 内连接
ABC
0b22
1c33
pd.merge(df1,df2,how = 'outer',on = "A") # 外连接
ABC
0a1.0NaN
1b2.02.0
2c3.03.0
3dNaN4.0

补充1个小技巧

df1[df1['A'].isin(df2['A'])] # 返回在df1中列'A'的值在df2中也存在的行
AB
1b2
2c3
df1[~df1['A'].isin(df2['A'])] # 返回在df1中列'A'的值在df2中不存在的行
AB
0a1

7 Pandas分组聚合

分组聚合(group by)顾名思义就是分2步:

  • 先分组:根据某列数据的值进行分组。用groupby()对某列进行分组

  • 后聚合:将结果应用聚合函数进行计算。在agg()函数里应用聚合函数计算结果,如sum()、mean()、count()、max()、min()等,用于对每个分组进行聚合计算。

import pandas as pd
import numpy as np
import random
df = pd.DataFrame({'A': ['a', 'b', 'a', 'b','a', 'b'],
                   'B': ['L', 'L', 'M', 'N','M', 'M'],
                   'C': [107, 177, 139, 3, 52, 38],
                   'D': [22, 59, 38, 50, 60, 82]})

df
ABCD
0aL10722
1bL17759
2aM13938
3bN350
4aM5260
5bM3882

单列分组

① 对单列分组后应用sum聚合函数

df.groupby('A').sum()
CD
A
a298120
b218191

② 对单列分组后应用单个指定的聚合函数

df.groupby('A').agg({'C': 'min'}).rename(columns={'C': 'C_min'})
C_min
A
a52
b3

③ 对单列分组后应用多个指定的聚合函数

df.groupby(['A']).agg({'C':'max','D':'min'}).rename(columns={'C':'C_max','D':'D_min'})
C_maxD_min
A
a13922
b17750

两列分组

① 对多列分组后应用sum聚合函数:

df.groupby(['A', 'B']).sum()
CD
AB
aL10722
M19198
bL17759
M3882
N350

② 对两列进行group 后,都应用max聚合函数

df.groupby(['A','B']).agg({'C':'max'}).rename(columns={'C': 'C_max'})
C_max
AB
aL107
M139
bL177
M38
N3

③ 对两列进行分组group 后,分别应用maxmin聚合函数

df.groupby(['A','B']).agg({'C':'max','D':'min'}).rename(columns={'C':'C_max','D':'D_min'})
C_maxD_min
AB
aL10722
M13938
bL17759
M3882
N350

补充1: 应用自定义的聚合函数

df = pd.DataFrame({'A': ['a', 'b', 'a', 'b','a', 'b'],
                   'B': ['L', 'L', 'M', 'N','M', 'M'],
                   'C': [107, 177, 139, 3, 52, 38],
                   'D': [22, 59, 38, 50, 60, 82]})

df
ABCD
0aL10722
1bL17759
2aM13938
3bN350
4aM5260
5bM3882
# 使用自定义的聚合函数计算每个分组的最大值和最小值
def custom_agg(x):
    return x.max() - x.min()
result =  df[['B','C']].groupby('B').agg({'C': custom_agg})
result
C
B
L70
M101
N0

补充2: 开窗函数(类似于SQL里面的over partition by):

使用transform函数计算每个分组的均值

# 使用transform函数计算每个分组的均值
df['B_C_std'] =  df[['B','C']].groupby('B')['C'].transform('mean')
df
ABCDB_C_std
0aL10722142.000000
1bL17759142.000000
2aM1393876.333333
3bN3503.000000
4aM526076.333333
5bM388276.333333

补充3: 分组聚合拼接字符串 pandas实现类似 group_concat 功能

假设有这样一个数据:

df = pd.DataFrame({
    '姓名': ['张三', '张三', '张三', '李四', '李四', '李四'],
    '科目': ['语文', '数学', '英语', '语文', '数学', '英语']
})

df
姓名科目
0张三语文
1张三数学
2张三英语
3李四语文
4李四数学
5李四英语

补充:按某列分组,将另一列文本拼接合并

按名称分组,把每个人的科目拼接到一个字符串:

# 对整个group对象中的所有列应用join 连接元素
(df.astype(str)# 先将数据全转为字符
.groupby('姓名')# 分组
.agg(lambda x : ','.join(x)))[['科目']]# join 连接元素
科目
姓名
张三语文,数学,英语
李四语文,数学,英语

  • 20
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值