首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【无痛学Python】Pandas统计分析基础,看这一篇就够了!

【无痛学Python】Pandas统计分析基础,看这一篇就够了!

作者头像
Skrrapper
发布2025-06-10 08:33:30
发布2025-06-10 08:33:30
90500
代码可运行
举报
文章被收录于专栏:技术分享技术分享
运行总次数:0
代码可运行

【Python数据分析】Pandas统计分析基础,看这一篇就够了!

Pandas是基于NumPy的数据分析模块,它提供了大量的数据分析会用到的工具,可以说Pnadas是Python能成为强大数据分析工具的重要原因之一。

导入方式:

import pandas as pd

Pandas中的数据结构

Pandas中包含三种数据结构:Series、DataFrame和Panel,中文翻译过来就是相当于序列、数据框和面板。

这么理解可能有点抽象,但是我们将其可以类比为:

  • Series对应数组
  • DataFrame对应表格
  • Panel对应Excel中的多表单Sheet

Series

它是一种一维数组对象,包含一个值序列,还有索引功能。

1.通过列表创建Series
代码语言:javascript
代码运行次数:0
运行
复制
import pandas as pd
obj = pd.Series([1,-2,3,-4]) # 仅仅由数组构成
print(obj)
代码语言:javascript
代码运行次数:0
运行
复制
0    1
1   -2
2    3
3   -4
dtype: int64

第一列为index索引,第二列为数据value。

当然,如果你不指定,就会默认用整形数据作为index,但是如果你想用别的方式来作为索引,你可以用别的方式。

代码语言:javascript
代码运行次数:0
运行
复制
i = ["a","b","c","d"]
v = [1,2,3,4]
t = pd.Series(v,index = i,name = "col") 
print(t)
代码语言:javascript
代码运行次数:0
运行
复制
a    1
b    2
c    3
d    4
Name: col, dtype: int64
2.通过字典创建Series

如果数据被放在字典中,就可以直接通过字典来创建Series。

代码语言:javascript
代码运行次数:0
运行
复制
# 字典创建Series
sdata = {'Joolin':20,'Jay':46}
obj2 = pd.Series(sdata)
print(obj2)
代码语言:javascript
代码运行次数:0
运行
复制
Joolin    20
Jay       46
dtype: int64

可以看到,由于字典使用键值对的方式,那么这样直接创建可以省去了创建index的操作。

当然,你也依旧可以指定你的index,那样就会覆盖原先的键。

代码语言:javascript
代码运行次数:0
运行
复制
sdata = {'Joolin':20,'Jay':46}
sp = ["Joolin","JJ"]
obj2 = pd.Series(sdata,index = sp)
print(obj2)
代码语言:javascript
代码运行次数:0
运行
复制
Joolin    20.0
JJ         NaN
dtype: float64

我们注意到,被覆盖的那些索引由于找不到与其匹配的值,就会显示**NaN,即“非数字”。或者如果你多写了没有对应值的索引元素,那么也会显示NaN**

代码语言:javascript
代码运行次数:0
运行
复制
sdata = {'Joolin':20,'Jay':46}
sp = ["Joolin","JJ","Jay"]
obj2 = pd.Series(sdata,index = sp)
print(obj2)
代码语言:javascript
代码运行次数:0
运行
复制
Joolin    20.0
JJ         NaN
Jay       46.0
dtype: float64

对于许多应用而言,Series有一个重要的功能:在算术运算中,它可以自动对齐不同索引的数据。

代码语言:javascript
代码运行次数:0
运行
复制
sdata = {'Joolin':20,'Jay':46}
states = ['Joolin','DT','Jay']
obj1 = pd.Series(sdata)
obj2 = pd.Series(sdata,index = states)
print(obj1+obj2)
代码语言:javascript
代码运行次数:0
运行
复制
DT         NaN
Jay       92.0
Joolin    40.0
dtype: float64

DataFrame

DataFrame是一个表格型的数据结构,它含有一组有序的列,每列都可以是不同的数据类型。我们来参考以下的表格进行理解:

name

city

year

0

张三

Beijing

2001

1

李四

Shanghai

2005

2

王五

Guangzhou

2003

这是一个典型的表格,我们看到它包含了例如name、city、year这样的列名,并且每一行都是根据索引自动排序。DataFrame也是这样一种结构,它既有行索引也有列索引,被看作是Series组成的字典。

我们既可以通过行索引进行操作,也可以通过列索引进行操作,并且注意,它们的优先性是相同的。

1.直接通过字典创建DataFrame

一般创建的方式就是通过字典,因为毕竟键值对的方式是最符合DataFrame的特点的。

代码语言:javascript
代码运行次数:0
运行
复制
data = {
	'name' : ['张三','李四','王五'],
	'city' : ['Beijing','Shanghai','Guangzhou'],
	'year' : [2001,2005,2003]
}
df = pd.DataFrame(data)
print(df)
代码语言:javascript
代码运行次数:0
运行
复制
  name       city  year
0   张三    Beijing  2001
1   李四   Shanghai  2005
2   王五  Guangzhou  2003

我们注意,DataFrame自动给我们加上了索引,并且会被有序排列;

如果我们指定列名序列,那么就会按照指定来进行列的顺序

代码语言:javascript
代码运行次数:0
运行
复制
df1 = pd.DataFrame(data,columns = ['city','year','name'])
代码语言:javascript
代码运行次数:0
运行
复制
        city  year name
0    Beijing  2001   张三
1   Shanghai  2005   李四
2  Guangzhou  2003   王五

如果我们指定行名序列,也就是标签label,那么就会按照指定标签而不再使用默认的0,1,2,3

代码语言:javascript
代码运行次数:0
运行
复制
df2 = pd.DataFrame(data,columns = ['city','year','name'],index = ['a','b','c'])
代码语言:javascript
代码运行次数:0
运行
复制
        city  year name
a    Beijing  2001   张三
b   Shanghai  2005   李四
c  Guangzhou  2003   王五

同Series一样,如果我们传入列在数据中找不到,那么就会产生NaN值,这里不再赘述。

索引对象

我们发现,Pandas有个很有用也很特别的东西——就是index索引,它在数据分析中可以起到很大的作用:因为数据往往都是庞大和繁杂的,如果我们直接通过数据本身来进行查找和处理,那么任务就会显得极其繁重。而如果数据有一个对应的值,或者特定的特点,那么就可以快速找到它,这就是索引

而每个索引对应的数据,就被称作索引对象

Pandas的索引对象负责管理轴标签和其他元数据,索引对象不能修改,否则会报错。也只有这样才能保证数据的准确性,并且保证索引对象在多个数据结构之间进行安全共享。

我们可以直接查看索引有哪些。

代码语言:javascript
代码运行次数:0
运行
复制
df2 = pd.DataFrame(data,columns = ['city','year','name'],index = ['a','b','c'])
print(df2.index)
print(df2.index[0])
print(df2.index[1])
print(df2.index[2])
代码语言:javascript
代码运行次数:0
运行
复制
Index(['a', 'b', 'c'], dtype='object')
a
b
c

同时索引也有它的方法和属性。

类别

方法/属性

描述

基本信息

dtype

返回索引的数据类型

size

返回索引的元素数量

shape

返回索引的形状

nbytes

返回索引的字节数

is_unique

判断索引是否唯一

is_monotonic_increasing

判断索引是否单调递增

is_monotonic_decreasing

判断索引是否单调递减

索引位置

get_loc()

返回指定值的索引位置

get_indexer()

返回多个值的索引位置

slice_indexer()

返回切片索引

contains()

判断索引是否包含某个值

元素操作

tolist()

将索引转换为Python列表

map()

对索引中的元素应用函数

astype()

改变索引的数据类型

repeat()

重复索引中的元素

drop()

删除指定元素

重构

rename()

重命名索引

reindex()

重新索引,支持缺失值填充

union()

返回两个索引的并集

intersection()

返回两个索引的交集

difference()

返回两个索引的差集

symmetric_difference()

返回两个索引的对称差集

排序

sort_values()

对索引进行排序

sortlevel()

按多级索引的某一层排序

唯一性与重复性

unique()

返回索引中的唯一值

duplicated()

标记重复值

其他

copy()

复制索引

equals()

判断两个索引是否相等

append()

追加一个新的索引

insert()

在指定位置插入元素

查看DataFrame的常用属性

包含valuesindexcolumnsndimshape

Pandas索引操作

1.重建索引

重建索引的格式:

obj.reindex()

索引对象是无法修改的,因此,重建索引指的是:对索引重新排序而不是重新命名,如果某个索引值不存在,则会引入缺失值。

这一点其实在上述的索引操作中已经体现出来了,这里再重新复述一下。

  • 缺失值默认为NaN,但是也可以通过fill_value来进行参数的填充。
代码语言:javascript
代码运行次数:0
运行
复制
obj = pd.Series([7,5,6,8],index=['a','b','d','c'])
print(obj)
obj = obj.reindex(['a','b','c','d','e'],fill_value = 0)
print(obj)
代码语言:javascript
代码运行次数:0
运行
复制
a    7
b    5
d    6
c    8
dtype: int64
a    7
b    5
c    8
d    6
e    0
dtype: int64
  • 对于一些特殊的序列,我们可以进行向前或者向后的拷贝填充,这样就会直接给缺失的地方填上已有的值。但我们要注意,因为仅仅是前向值或者后向值的填充,那么没有被填充的地方依旧显示缺失值。 ffillpad:前向值填充 bfillbackfill:后向值填充
  • reindex既可以修改行索引也可以修改列索引,也可以都修改,这根据需求灵活使用即可。

2.更换索引

如果我们觉得以前的那个索引方法不适用了,不想要了,那么可以使用set_index来进行索引的更换。

代码语言:javascript
代码运行次数:0
运行
复制
df = df.set_index('city')
print(df)
代码语言:javascript
代码运行次数:0
运行
复制
          name  year
city                
Beijing     张三  2001
Shanghai    李四  2005
Guangzhou   王五  2003

注意,如果你有这种想法:我想直接更换为新的索引,比如set_index(['a','b','c'])

是不行的,因为这个方法本身只能使用已有的索引,而不能创造新的索引,会这样报错:

代码语言:javascript
代码运行次数:0
运行
复制
KeyError: "None of ['a', 'b', 'c'] are in the columns"

DataFrame数据的查询与编辑

1.DataFrame数据的查询

这里就会着重用到我们的索引功能来进行查询了。查询分为四种:选取列、选取行、选取行和列、布尔选择

A.选取列
  • 单列查询
代码语言:javascript
代码运行次数:0
运行
复制
df['column_name']        # 返回一个Series
df.column_name           			 # 等价于上面的方法
  • 多列查询
代码语言:javascript
代码运行次数:0
运行
复制
df[['col1', 'col2']]                  # 返回一个DataFrame

示例:

代码语言:javascript
代码运行次数:0
运行
复制
w1 = df['city']          # 返回一个Series
print(w1)
w2 = df.year             # 等价于上面的方法
print(w2)
w3 = df[['city','year']] # 多列查询
  • 同时,也可以使用select_dtypes等方法指定查询的范围:

示例:

代码语言:javascript
代码运行次数:0
运行
复制
w4= df.select_dtypes(exclude = 'int64').head() # 除了int64类型以外的其他列
print(w4)
代码语言:javascript
代码运行次数:0
运行
复制
  name       city
0   张三    Beijing
1   李四   Shanghai
2   王五  Guangzhou
B.选取行
  • 针对行,我们可以使用切片操作注意:列是不能使用切片操作的!
代码语言:javascript
代码运行次数:0
运行
复制
print(df[:2]) # 显示前两行
print(df[1:3]) # 显示第2-3行
  • 当然,也可以用其他方法,例如headtail方法,但它们获得的都是头部和尾部开始的数据,具有局限性。注意:当使用这两个方法不输入参数的时候,是默认前5行和后5行。
  • 也可以用sample来抽取随机样本。
C.选取行和列

鉴于切片方法选取行有很大的局限性,我们一般使用更方便的方法来进行行和列的选取。

loc(行索引名称或条件,列索引名称)

代码语言:javascript
代码运行次数:0
运行
复制
# 显示name和year两列
print(df.loc[:,['name','year']])
# 显示北京和上海的name和year两列
print(df.loc[['Beijing','Shanghai'],['name','year']])
# 显示year大于等于2002的name和year两列
print(df.loc[df['year']>=2002,['name','year']])

loc与其他索引方法例如isin配合使用可以指定查询数据,有没有数据库的感觉?

iloc(行索引位置,列索引位置)

代码语言:javascript
代码运行次数:0
运行
复制
# 选取前两列
print(df.iloc[:,2])
# 选取第1和第3行
print(df.iloc[[0,2]])

query(self,expr,inplace = False,**kwargs)

其中expr是要查询的字符串,kwargs是dict关键字参数。

D.布尔选择

在Pandas中可以使用逻辑运算符实现布尔选择。

2.DataFrame数据的编辑

这一部分就涉及到经典的 增删改 操作。注意在Pandas中,我们要先将数据提取出来,再进行编辑。(当然这一部分是原理,我们直接用方法就完事了)

A.增加数据

增加列

直接赋值法

代码语言:javascript
代码运行次数:0
运行
复制
data = {'name': ['Alice', 'Bob', 'Charlie'],
        'age': [25, 30, 35]}
df = pd.DataFrame(data)

# 直接添加新列
df['city'] = ['New York', 'Los Angeles', 'Chicago']
print(df)

输出:

代码语言:javascript
代码运行次数:0
运行
复制
      name  age           city
0    Alice   25       New York
1      Bob   30    Los Angeles
2  Charlie   35        Chicago

使用assign()方法

代码语言:javascript
代码运行次数:0
运行
复制
df = df.assign(country=['USA', 'USA', 'USA'])
print(df)

输出:

代码语言:javascript
代码运行次数:0
运行
复制
      name  age           city  age_in_5_years country
0    Alice   25       New York               30     USA
1      Bob   30    Los Angeles               35     USA
2  Charlie   35        Chicago               40     USA

增加行

使用append方法

代码语言:javascript
代码运行次数:0
运行
复制
# 这种方法在Pandas 2.0以后已经被弃用,推荐使用concat()
new_row = pd.DataFrame([['Eve', 27, 'Boston', 32, 'USA']], 
                       columns=df.columns)
df = pd.concat([df, new_row], ignore_index=True)
print(df)

输出:

代码语言:javascript
代码运行次数:0
运行
复制
name  age              city  age_in_5_years country
0    Alice   25          New York               30     USA
1      Bob   30       Los Angeles               35     USA
2  Charlie   35           Chicago               40     USA
3    David   28     San Francisco               33     USA
4      Eve   27            Boston               32     USA
B.删除数据

删除数据直接使用**drop**方法,参数axis来确定删除行还是列。

注意,默认是不删除原数据,如果想要再原数据上删除应设置参数inplace = True。

代码语言:javascript
代码运行次数:0
运行
复制
# 删除单列
df1 = df.drop(columns=['city'], inplace=False)
# print(df)
print(df1)
print(df)
# 同时删除多个列
df.drop(columns=['age', 'country'], inplace=True)
print(df)
代码语言:javascript
代码运行次数:0
运行
复制
      name  age country
0    Alice   25     USA
1      Bob   30     USA
2  Charlie   35     USA

      name  age         city country
0    Alice   25     New York     USA
1      Bob   30  Los Angeles     USA
2  Charlie   35      Chicago     USA

      name         city
0    Alice     New York
1      Bob  Los Angeles
2  Charlie      Chicago
C.修改数据

修改数据直接对选择的数据赋值即可,但是注意,这里是直接修改数据的值,操作无法撤销,修改了就是修改了。

我们也可以使用replace(to_place,value)进行数据的替换

to_place是被替换的值;value是要替换成的值。

D.修改列名

直接rename()修改。注意是用键值对形式。

Pandas数据运算

算术运算

原则:有相同索引——进行算术运算;没有相同索引——进行数据对齐,并引入缺失值。

意思就是说,如果没有相同的索引,那么就不会进行运算,并且如果你原先数据位上有值,也会被当初NaN。看例子来理解:

代码语言:javascript
代码运行次数:0
运行
复制
s3 = pd.Series([100, 200, 300], index=['a', 'b', 'd'])
print(s1 + s3)
代码语言:javascript
代码运行次数:0
运行
复制
a    110.0
b    220.0
c      NaN
d      NaN
dtype: float64

针对Series和DataFrame。都会数据对齐操作,后者是会同时发生在行和列上。

代码语言:javascript
代码运行次数:0
运行
复制
df1 = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})
df2 = pd.DataFrame({'A': [10, 20, 30], 'D': [40, 50, 60]})

print(df1 + df2)  # 按元素相加
代码语言:javascript
代码运行次数:0
运行
复制
    A   B   D
0  11 NaN NaN
1  22 NaN NaN
2  33 NaN NaN

函数应用和映射

如果需要进行较为复杂的运算,那么就会需要自己定义函数。如何将自己的函数使用到数据运算中呢?Pandas提供了三种方法。

  • map函数:针对Series的操作,将函数套用到每个元素中
  • apply函数:针对DataFrame的操作,将函数套用到行与列上,通过axis参数设置
  • applymap函数:针对DataFrame的操作,将函套用到每个元素中

排序

对于Series

排序有两种方法:

  • sort_index:对索引进行排序,默认为升序,ascending=False时为降序
  • sort_values:对数据进行排序。

对于DataFrame

通过指定轴的方向,使用:

  • sort_index:对行或列的索引进行排序
  • sort_values:将列名传给by参数进行列排序

汇总与统计

数据汇总

使用sum方法,默认对每列进行汇总。axis=1时对行进行汇总。

数据描述与统计

使用describe方法,会统计初步的数据特征,当然,一般都是其他方法进行更详细的描述与统计。

方法

说明

count()

非空值个数

sum()

求和

mean()

平均值

median()

中位数

mode()

众数

std()

标准差

var()

方差

min()

最小值

max()

最大值

idxmin()

最小值的位置

idxmax()

最大值的位置

数据分组与聚合

1.数据分组

1.基本使用

根据某个或几个字段对数据集进行分组,然后对每个分组进行分析与转换,这是数据分析的常见操作。

在Pandas中可以使用groupby方法来进行数据分组操作。

数据分组后返回的数据类型不再是一个数据框,而是一个groupby对象。

2.按列名分组
代码语言:javascript
代码运行次数:0
运行
复制
groupk1 = df.groupby('Salary').mean()
3.按列表或元组分组
代码语言:javascript
代码运行次数:0
运行
复制
data = {
    'Department': ['HR', 'HR', 'IT', 'IT', 'Finance', 'Finance', 'HR'],
    'Name': ['Alice', 'Bob', 'Charlie', 'David', 'Eve', 'Frank', 'Grace'],
    'Salary': [5000, 7000, 8000, 9000, 6000, 10000, 7500],
    'Age': [25, 30, 35, 40, 28, 32, 26]
}

df = pd.DataFrame(data)

# 按部门分组
grouped = df.groupby('Department')
print(grouped.size())
4.按字典分组

通过字典作为分组键。

5.按函数分组

函数作为分组键的原理类似于字典,使用映射关系来进行分组。

数据聚合

数据聚合就是对分组后的数据进行计算,产生标量值的数据转换过程。

1.聚合函数

函数

说明

sum()

计算总和

mean()

计算平均值

median()

计算中位数

min()

计算最小值

max()

计算最大值

count()

计算非空值的个数

std()

计算标准差

var()

计算方差

prod()

计算乘积

first

第一个值

last

最后一个值

2.使用agg方法聚合数据

aggaggregate方法都是通过自定义聚合函数来进行数据的聚合。它们可以直接对DataFrame进行函数应用操作。

代码语言:javascript
代码运行次数:0
运行
复制
print(grouped['Salary'].agg([np.sum,np.mean]))
代码语言:javascript
代码运行次数:0
运行
复制
              sum    mean
Department               
Finance     16000  8000.0
HR          19500  6500.0
IT          17000  8500.0

如果希望返回的结果不以分组键为索引,可以通过as_index = False来实现。

3.分组运算

分组运算包含聚合运算,聚合运算是数据转换的特例。

transform方法

可以将运算分布到每一

代码语言:javascript
代码运行次数:0
运行
复制
data = {
    'Department': ['HR', 'HR', 'IT', 'IT', 'Finance', 'Finance', 'HR'],
    'Salary': [5000, 7000, 8000, 9000, 6000, 10000, 7500]
}

df = pd.DataFrame(data)

# 计算每个部门内的工资占比
df['Salary_Ratio'] = df.groupby('Department')['Salary'].transform(lambda x: x / x.sum())
print(df)
代码语言:javascript
代码运行次数:0
运行
复制
  Department  Salary  Salary_Ratio
0         HR    5000       0.256410
1         HR    7000       0.358974
2         IT    8000       0.470588
3         IT    9000       0.529412
4    Finance    6000       0.375000
5    Finance   10000       0.625000
6         HR    7500       0.384615

apply方法

可以将运算分布到每一

代码语言:javascript
代码运行次数:0
运行
复制
# 计算工资税后收入(假设税率20%)
df['Net_Salary'] = df['Salary'].apply(lambda x: x * 0.8)

# 计算每个部门的工资方差
variance = df.groupby('Department')['Salary'].apply(lambda x: x.var())
print(df)
print(variance)
代码语言:javascript
代码运行次数:0
运行
复制
  Department  Salary  Net_Salary
0         HR    5000       4000.0
1         HR    7000       5600.0
2         IT    8000       6400.0
3         IT    9000       7200.0
4    Finance    6000       4800.0
5    Finance   10000       8000.0
6         HR    7500       6000.0

Department
Finance    8000000.0
HR         833333.0
IT         500000.0
Name: Salary, dtype: float64
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-06-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Pandas中的数据结构
    • Series
      • 1.通过列表创建Series
      • 2.通过字典创建Series
    • DataFrame
      • 1.直接通过字典创建DataFrame
    • 索引对象
    • 查看DataFrame的常用属性
  • Pandas索引操作
    • 1.重建索引
    • 2.更换索引
  • DataFrame数据的查询与编辑
    • 1.DataFrame数据的查询
      • A.选取列
      • B.选取行
      • C.选取行和列
      • D.布尔选择
    • 2.DataFrame数据的编辑
      • A.增加数据
      • B.删除数据
      • C.修改数据
      • D.修改列名
  • Pandas数据运算
    • 算术运算
    • 函数应用和映射
    • 排序
    • 汇总与统计
      • 数据汇总
      • 数据描述与统计
  • 数据分组与聚合
    • 1.数据分组
      • 1.基本使用
      • 2.按列名分组
      • 3.按列表或元组分组
      • 4.按字典分组
      • 5.按函数分组
    • 数据聚合
      • 1.聚合函数
      • 2.使用agg方法聚合数据
      • 3.分组运算
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档