四、Pandas数据处理

Pandas 数据处理

(一)Pandas库简介

1. Pandas

Pandas是一个开源的、用于数据处理和分析的Python库,特别适合处理表格类数据。它建立在NumPy 数组之上,提供了高效的数据结构和数据分析工具,使得数据操作变得更加简单、便捷和高效。

2. 核心

(1)数据结构

Series:一维数组,可以存储任何数据类型(整数、字符串、浮点数等),每个元素都有一个与之对应的标签(索引)。

DataFrame:二维表格型数据结构,可以视为++多个 Series 对象的集合++ ,每一列都是一个 Series。 每列可以有不同的数据类型,并且有行和列的标签。

(2)数据操作

读取和保存数据:支持多种数据格式,如 CSV、Excel、SQL 数据库、JSON 等。

数据选择和过滤:提供灵活的索引和条件筛选功能,方便数据的提取和过滤。

数据清洗:提供了处理缺失数据、重复数据、异常值等数据清洗功能。

数据转换:通过 apply() , map() , replace() 等方法进行数据转换。

数据合并:使用 concat() , merge() , join() 等方法进行数据的横向和纵向合并。

聚合和分组:使用 groupby() 结合 agg() , transform() 等方法进行数据的分组和聚合。

3. 主要特点

数据结构:Pandas提供了两种主要的数据结构:Series(一维数组)和DataFrame(二维表 格)。

数据操作:支持数据的增、删、改、查等操作,以及复杂的数据转换和清洗。

数据分析:提供丰富的数据分析方法,如聚合、分组、透视等。

文件读取与写入:支持多种文件格式(如CSV、Excel、SQL等)的读取和写入。

与其他库集成良好:Pandas 与许多其他三方库(如 NumPy、Matplotlib、Scikit-learn等)无缝集成,形成了一个强大的数据科学生态系统。

强大的社区支持:Pandas 拥有庞大的开发者社区,提供丰富的资源和学习材料。

4. Pandas的安装

Pandas是一个第三方库,并不属于Python的系统库,需要进行安装,可输入以下命令进行安装:

pip install pandas

(二)一维数组 Series

一维数组可以理解为excel中的一列数据:

标签 -- 可以是默认的,也可以是指定的

1. Series的创建

在Pandas中,一维数组的创建离不开Pandas库中的Series类。

class pandas.Series(data=None, index=None, dtype=None, name=None, copy=None, fastpath=False)

data:可以是以下几种类型的数据:

  • 标量值,如整数或字符串
  • Python列表或元组
  • Python字典
  • 1d-Ndarray

index:数组或列表,用于定义Series的索引。如果未提供,则默认为从0开始的整数索引。

dtype:指定Series的数据类型。

name:给Series一个名字,用于后续的索引和操作。

copy:布尔值,默认为False【新版本的若指定索引了,会强制复制,即copy=True】。如果为True,则复制数据;如果为False,则尽可能避免复制数据, 仅影响Ndarray输入。

fastpath:布尔值,默认为False,通常不需要用户指定。它是Pandas库内部使用的一个优化标 志,当设置为 True 时,允许 Series 构造函数绕过一些检查和验证步骤,加快Series的创建速度。 但由于这个参数跳过了某些安全检查,因此在正常使用中,如果在创建Series时设置了 fastpath=True ,而传入的数据又不符合预期,则可能会导致不可预测的行为或错误。

(1)使用标量创建

python 复制代码
import pandas as pd

# 定义一个变量 data,并赋值为5
data = 5

# 使用 pandas 库的 Series 函数创建一个 Series 对象
# 第一个参数是要作为 Series 数据的值,这里是 0
# 第二个参数必须是一个列表或数组,用于指定 Series 的索引,这里指定了索引为 ['a', 'b', 'c']

series = pd.Series(data, index=['a', 'b', 'c'])
# 打印输出创建好的Series对象
print(series)
print(type(series))

series = pd.Series(data, index=['A', 'b', 'c'], name='test')
# 打印输出创建好的Series对象
print(series)
print(type(series))

series = pd.Series(data, index=['A', 'B', 'c'], name='test2', dtype=str)
# 打印输出创建好的Series对象
print(series)
print(type(series))

运行结果:

复制代码
a    5
b    5
c    5
dtype: int64
<class 'pandas.Series'>
A    5
b    5
c    5
Name: test, dtype: int64
<class 'pandas.Series'>
A    5
B    5
c    5
Name: test2, dtype: str
<class 'pandas.Series'>

(2)使用列表或元组创建

python 复制代码
import pandas as pd

# 定义一个列表 data1,其中包含了整数 1 到 5
data1 = [1, 2, 3, 4, 5]

# 定义一个元组 data2,其中包含了整数 5 到 1
data2 = (5, 4, 3, 2, 1)

# 使用 pandas 库的 Series 函数创建第一个 Series 对象 series1
# 第一个参数 data1 是要作为 Series1 数据的值,即列表[1, 2, 3, 4, 5]
# 第二个参数是一个列表 ['a', 'b', 'c', 'd', 'e'],用于指定 Series1 的索引
series1 = pd.Series(data1, index=['a', 'b', 'c', 'd', 'e'])

# 使用 pandas 库的 Series 函数创建第二个 Series 对象 series2
# 第一个参数 data2 是要作为 Series2 数据的值,即元组(5, 4, 3, 2, 1)
# 第二个参数是一个列表 ['a', 'b', 'c', 'd', 'e'],用于指定 Series2 的索引
series2 = pd.Series(data2, index=['a', 'b', 'c', 'd', 'e'])

# 打印输出创建好的第一个 Series 对象 series1
print(series1)

# 打印输出创建好的第二个 Series 对象 series2
print(series2)

运行结果:

复制代码
a    1
b    2
c    3
d    4
e    5
dtype: int64
a    5
b    4
c    3
d    2
e    1
dtype: int64

(3)使用字典创建

使用字典创建 Series 时,字典的键就是索引,字典的值就是该索引对应的值。如果使用字典创建 Series,并且指定了与字典的键不同的 index 参数,那么生成的 Series 数组中的数据就是以 index 参数的值为索引,但索引所对应的值是 NaN。 在 Pandas 中, NaN (Not a Number)是一个特殊的浮点数,用于表示缺失数据或无效数据。 NaN 是 IEEE 浮点标准的一部分,Pandas 使用 NaN 来表示数据集中缺失或未定义的值。

python 复制代码
import pandas as pd

# 定义一个字典 data,其中包含了三个键值对,键分别为'a'、'b'、'c',对应的值分别为1、2、3
data = {'a': 1, 'b': 2, 'c': 3}

# 使用 pandas 库的 Series 函数创建一个 Series 对象。
# 当传入一个字典作为参数时,字典的键会自动成为 Series 的索引,字典的值会成为对应索引下的数值。
series = pd.Series(data)

# 打印输出创建好的Series对象
print(series)

# 若依旧指定了与字典的键不同的 index 参数,则会以 index 参数的值为索引,但索引所对应的值全为 NaN
# 只要指定了 index 参数,无论指定多少个参数都会返回指定数量的 NaN,不会输出字典的值
series = pd.Series(data, index=['x', 'y', 'z'])
series2 = pd.Series(data, index=['x', 'y'])

# 打印输出创建好的Series对象
print(series)
print(series2)

运行结果:

复制代码
a    1
b    2
c    3
dtype: int64
x   NaN
y   NaN
z   NaN
dtype: float64
x   NaN
y   NaN
dtype: float64

(4)使用Ndarray创建

python 复制代码
import pandas as pd
import numpy as np

# 使用 numpy 的 array 函数创建一个一维数组 data,数组中包含了整数 1 到 5
data = np.array([1, 2, 3, 4, 5])

# 使用 pandas 库的 Series 函数创建一个 Series 对象
# 传入刚刚创建的一维 numpy 数组 data 作为参数,此时会将该数组的数据依次作为 Series 的数值
# 并且会自动生成一个默认的整数索引(从 0 开始,依次递增,与数组元素的下标对应)
# 自定义索引会强制复制,即 copy=True
series = pd.Series(data,index=['a', 'b', 'c', 'd', 'e'],copy=False)

# 新版本的 panda,使用 series[0] 会添加元素,而不会将 series[0] 按位置索引工作
# series[0] = 100
series.iloc[0] = 100


# 打印输出创建好的 Series 对象,以便查看其具体内容,包括索引和对应的数据值等信息。
print(series)
print(data)

运行结果:

复制代码
a    100
b      2
c      3
d      4
e      5
dtype: int64
[100   2   3   4   5]

2. Series的属性(16)

(1)index

返回Series中的索引,可赋值修改

python 复制代码
import pandas as pd

# 创建 Series 数组
series = pd.Series([1, 2, 3], index=['a', 'b', 'c'])

# 打印输出该 Series 对象的索引。
# Series 对象的 index 属性可以获取到它的索引信息,这里会输出索引 -- ['a', 'b', 'c']。
print(series.index)

# 重新给 Series 对象的索引赋值。
# 将原来的索引 -- ['a', 'b', 'c'],修改为新的索引 -- ['e', 'f', 'g'],
# 这会改变 Series 对象中每个数据元素对应的索引标识。
series.index = ['e', 'f', 'g']	# 数量必须一一对应,不能少,不能多

# 再次打印输出修改索引后的 Series 对象,
print(series)

运行结果:

复制代码
Index(['a', 'b', 'c'], dtype='str')
e    1
f    2
g    3
dtype: int64

(2)values

只读属性,用于返回Series中的数据,返回的数据将以Ndarray数组的形式存在。

python 复制代码
import pandas as pd

# 创建 Series 数组
series = pd.Series([1, 2, 3], index=['a', 'b', 'c'])

# 打印输出该 Series 对象的数据。
print(series.values)
print(type(series.values))

# # values无法通过直接赋值的方式去修改
# series.values = ['e', 'f', 'g']
# print(series)

运行结果:

复制代码
[1 2 3]
<class 'numpy.ndarray'>

(3)name

用于返回Series的名称,如果创建时指定了name参数,那么该属性的返回值就是name参数,如果没有指定则为None,可赋值修改

python 复制代码
import pandas as pd

# 创建 Series 数组
series = pd.Series([1, 2, 3], index=['a', 'b', 'c'])

# 打印输出该 Series 对象的name属性值。
print(series.name)

# 给 Series 对象的 name 属性赋值为 'test'。
# 这相当于给这个 Series 对象起了一个名字,方便在后续处理或展示数据时进行识别和区分。
series.name = 'test'

# 再次打印输出该 Series 对象的 name 属性值,
print(series.name)

运行结果:

复制代码
None
test

(4)dtype和dtypes

对于Series来说,dtype和dtypes的作用是一样的,都是用来返回Series对象的数据类型。

需要注意的是:属性都为只读属性,不可以通过直接赋值的方式去修改数据类型。

python 复制代码
import pandas as pd

# 创建 Series 数组
series = pd.Series([1, 2, 3], index=['a', 'b', 'c'])

# 打印输出该 Series 对象的数据类型。
# Series 对象的 dtype 属性可以获取到其数据的类型,这里创建的 Series 数据是整数类型,所以会输出 'int64'。
print(series.dtype)

# Series 对象的 dtype 属性是只读属性,不可以直接通过赋值的方式来改变数据类型。
# 要改变 Series 对象的数据类型,需要使用 astype 等合适的方法来进行转换操作。

# series.dtype = 'float32'
# print(series.dtype)

(5)shape

用于描述Series的形状,该返回值是一个元组。

python 复制代码
import pandas as pd
import numpy as np

# 创建 Series 数组
series = pd.Series([1, 2, 3], index=['a', 'b', 'c'])
arr = np.array([1,2,3])

# 打印数组的形状
print(series.shape)
print(arr.shape)

运行结果:

复制代码
(3,)
(3,)

(6)size

用于返回Series的元素数量,该返回值是一个整数。

python 复制代码
import pandas as pd

# 创建 Series 数组
series = pd.Series([1, 2, 3], index=['a', 'b', 'c'])

# 打印数组元素的元素数量
print(series.size)	# 打印:3

(7)empty

用来表示Series数组是否为空,返回值一个布尔值

如果数组里一个元素都没有就返回True,否则返回 False。

python 复制代码
import pandas as pd

# 创建Series数组
series = pd.Series()
series2 = pd.Series([1,2,3])

# 判断数组是否为空
print(series.empty)	# True
print(series2.empty)	# False

(8)hasnans

用于返回数组中是否包含NaN值,如果数组中存在NaN,那么返回True,否则返回False。

python 复制代码
import pandas as pd
import numpy as np

# 创建 Series 数组
# 用 numpy 下的 nan 替代无效,缺失数据
series = pd.Series([1, 2, 3, np.nan], index=['a', 'b', 'c', 'd'])
series2 = pd.Series([np.nan])   # 是空值,但不代表数组为空

# 判断数组是否存在 NaN 值
print(series)
print(series.hasnans)   # True
print(series2.empty)    # False

(9)is_unique

用于返回数组中的元素是否为独一无二的,如果所有的元素都是独一无二的,即数组中没有重复元素, 那么就返回True,否则返回False。

python 复制代码
import pandas as pd

# 创建 Series 数组
series = pd.Series(['a', 'b', 'c'])

# 判断数组中是否存在重复的元素
print(series.is_unique)	# True

(10)nbytes

用于返回该 Series 对象中所有数据占用的总字节数。

python 复制代码
import pandas as pd

# 创建 Series 数组
series = pd.Series([1, 2, 3, 4, 5], dtype='int64')

# 获取数组元素所占用的内存大小
print(series.nbytes)	# 40

(11)axes

用于返回 series 对象行轴标签的列表。

和 index 差不多

python 复制代码
import pandas as pd

# 创建 Series 数组
series = pd.Series([1, 2, 3, 4, 5], index=['a', 'b', 'c', 'd', 'e'], dtype='int64')

# 获取数组的行轴标签
print(series.axes)  # [Index(['a', 'b', 'c', 'd', 'e'], dtype='str')]

(12)ndim

返回 Series 数组的维度,对于Series数组来说,它的维度始终为1。

python 复制代码
import pandas as pd

# 创建 Series 数组
series = pd.Series([1, 2, 3, 4, 5], index=['a', 'b', 'c', 'd', 'e'], dtype='int64')

# 获取数组的索引
print(series.ndim)  # 1

(13)array

用于返回 Series 的底层数组,包括数组的元素、数组的长度及数组元素的数据类型。

python 复制代码
import pandas as pd
import numpy as np

# 创建一个 NumPy 数组
data = np.array([1, 2, 3, 4, 5])

# 使用 NumPy 数组创建一个 Pandas Series
series = pd.Series(data)

# 打印 Series 的底层数据作为一个 Pandas 的 Array 对象
print(series.array)

# 打印上述 Array 对象的类型
print("\n",type(series.array))

运行结果:

复制代码
<NumpyExtensionArray>
[1, 2, 3, 4, 5]
Length: 5, dtype: int64

<class 'pandas.arrays.NumpyExtensionArray'>

(14)attrs

返回 series 的自定义属性,可以用来存储额外的说明性数据。

python 复制代码
import pandas as pd

# 创建一个包含整数 1 到 5 的 Pandas Series
series = pd.Series([1, 2, 3, 4, 5])

# 打印额外的属性
print(series.attrs,"\n")

# 给 Series 添加额外的属性,这里添加了来源和时间信息
series.attrs = {'source': 'file1', 'time': '19:27:27'}

# 打印 Series 本身,将显示其数据和索引
print(series)

# 打印 Series 的额外属性
print('\n额外属性', series.attrs)

运行结果:

复制代码
{} 

0    1
1    2
2    3
3    4
4    5
dtype: int64

额外属性 {'source': 'file1', 'time': '19:27:27'}

(15)is_monotonic_decreasing

返回一个布尔值,表示 Series 是否按降序排列。

python 复制代码
import pandas as pd

# 创建一个 Pandas Series,其值从 5 递减到 1
series = pd.Series([5, 4, 3, 2, 1])

# 打印检查 Series 是否单调递减的结果
# 由于 Series 中的值是递减的,所以这个表达式将返回 True
print(series.is_monotonic_decreasing)

(16)is_monotonic_increasing

返回一个布尔值,表示 Series 是否按升序排列。

python 复制代码
import pandas as pd

# 创建一个 Pandas Series,其值从 1 递增到 5
series = pd.Series([1, 2, 3, 4, 5])

# 打印检查 Series 是否单调递增的结果
# 由于 Series 中的值是递增的,所以这个表达式将返回 True
print(series.is_monotonic_increasing)

3. Series中元素的索引与访问

(1)位置索引

可以使用整数索引来访问Series中的元素,就像访问列表一样。

python 复制代码
import pandas as pd

# 创建一个 Series
series = pd.Series([10, 20, 30, 40, 50])

# 通过位置索引获取元素
print(series[0])
print(series[2])

(2)标签索引

除了使用位置索引之外,还可以使用标签进行索引,与访问字典中的元素类似。

python 复制代码
import pandas as pd

# 创建一个带有标签的 Series
series = pd.Series([10, 20, 30, 40, 50], index=['a', 'b', 'c', 'd', 'e'])

# 通过标签索引获取元素
print(series['a'])
print(series['c'])

(3)切片索引

Series对象的切片方式有两种,第一种是使用位置切片,其使用方法与列表的切片类似;第二种是使用标签切片,其语法与位置切片类似,都是 start:stop ,且开始值与终止值可以省略,但与位置切片不同的是,标签切片的范围是左右都闭合,即既包含start,又包含stop,而位置切片是左闭右开,只包含 start,不包含stop。

python 复制代码
import pandas as pd

# 创建一个带有标签的 Series
series = pd.Series([10, 20, 30, 40, 50], index=['a', 'b', 'c', 'd', 'e'])

# 通过位置切片
print(series[:]) 

# 通过标签切片
print(series['b':'d'])

(4)loc与iloc

loc与iloc也是Series对象的属性,它们的作用就是用来访问Series中的元素

loc是基于标签的索引,iloc 是基于切片、位置的索引。

python 复制代码
import pandas as pd

# 创建一个带有标签的 Series
series = pd.Series([10, 20, 30, 40, 50], index=['a', 'b', 'c', 'd', 'e'])

# 使用 .loc 通过标签索引
print(series.loc['a'])

# 使用 .iloc 通过切片、位置索引
print(series.iloc[0:2])
print(series.iloc[2])

运行结果:

复制代码
10
a    10
b    20
dtype: int64
30

(5)at与iat

at 与 iat 也是Series对象的属性,可以用来访问元素

at 是基于标签的索引,iat是基于位置的索引

python 复制代码
import pandas as pd

# 创建一个带有标签的 Series
series = pd.Series([10, 20, 30, 40, 50], index=['a', 'b', 'c', 'd', 'e'])

# 使用 .at 通过标签索引
print(series.at['a'])

# 使用 .iat 通过位置索引
print(series.iat[0])
print(series.iat[2])

(6)head

head 是 Series 对象的方法,用于快速查看 Series 数据的开头部分内容

series.head(n=None)

n :是可选参数,用于指定要返回的行数。如果不提供该参数,默认值为 5 。

python 复制代码
import pandas as pd

# 创建一个 Series 对象
data = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
index = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
series = pd.Series(data, index=index)

# 使用 head 函数查看前 5 行数据
print(series.head())

(7)tail

tail的用法与head类似,但不同的是,它用于快速查看 Series 数据的末尾部分内容

series.tail(n=None)

n :是可选参数,用于指定要返回的行数。若不提供该参数,默认值为 5 。

python 复制代码
import pandas as pd

# 创建一个 Series 对象
data = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
index = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
series = pd.Series(data, index=index)

# 使用 tail 函数查看后 5 行数据
print(series.tail())

(8)isin

该函数用于判断 Series 中的每个元素是否在指定的一组值中

返回一个与原 Series 长度相同的布尔型 Series ,其中对应位置为 True 表示该位置的元素在指定的值集合中, False 则表示不在

series.isin(values)

values :是一个可迭代对象(如列表、元组、集合等),用于指定要进行判断的一组值。

python 复制代码
import pandas as pd

# 创建一个 Series 对象(被检查的值)
data = [10, 20, 30, 40, 50]
series = pd.Series(data)

# 指定要判断的一组值(要检查的值)
values_to_check = [20, 40]

# 使用 isin 函数进行判断 -- 判断 series 是否在 values_to_check 中
result = series.isin(values_to_check)
print(result)

(9)get

Series.get 方法用于通过标签来获取 Series 中的元素。

Series.get(key, default=None)

key : 你想要获取的元素的标签。

default : 可选参数,如果 key 不在标签中,返回这个默认值。如果没有指定,默认为 None 。

python 复制代码
import pandas as pd

# 创建一个示例 Series
s = pd.Series(['apple', 'banana', 'cherry'], index=[1, 2, 3])

# 使用 get 方法获取元素
print(s.get(2)) 
print(s.get(4, 'Not Found')) 

4. 数据操作

(1)数据清洗

数据清洗指对 Series 对象中的某些值进行删除、修改等操作,分别使用以下方法:

dropna():删除包含NaN值的行。

series.dropna(axis=0, inplace=False)

axis :可选参数,用于指定按哪个轴删除缺失值。对于 Series 对象,因为它是一维数据结构, 只有一个轴,所以此参数默认值为 0 ,且一般不需要修改这个参数(在处理 DataFrame 时该参数 才有更多实际意义,如 axis = 0 表示按行删除, axis = 1 表示按列删除)。

inplace :可选参数,用于指定是否在原 Series 对象上进行操作。如果 inplace = True ,则会 直接在原 Series 上删除缺失值,原 Series 会被修改;如果 inplace = False (默认值),则会 返回一个删除了缺失值的新 Series ,原 Series 保持不变。

python 复制代码
import pandas as pd
import numpy as np

# 创建一个包含缺失值的 Series 对象
data = [1, np.nan, 3, 4, np.nan]
series = pd.Series(data)

# 使用 dropna 函数删除缺失值,返回新的 Series
new_series = series.dropna()
print(new_series)

fillna():填充NaN值。

Series.fillna(value=None, method=None, axis=None, inplace=False, limit=None, downcast=None)

++pandas 的新版本(2.1+)中 fillna() 的 method 参数已被弃用。++

现在应该使用专门的方法:(只有向前、向后填充改了)

  • 前向填充: ffill() 或 fillna(method='ffill') → 改为 ffill()
  • 后向填充: bfill() 或 fillna(method='bfill') → 改为 bfill()

value :用于填充缺失值的标量值或字典。如果传递的是字典,则字典的键应该是要填充的标签,值是用于填充的值。

method :字符串,表示填充的方法。可选值包括:

  • pad / ffill :用前一个非缺失值去填充缺失值。
  • bfill / backfill :用后一个非缺失值去填充缺失值。

axis :填充的轴,对于 Series 对象来说,这个参数通常不需要指定,因为 Series 是一维的。

inplace :布尔值,表示是否在原地修改数据。如果为 True ,则直接在原 Series 上修改,不返回新的对象。

limit :整数,表示最大填充量。如果指定,则只填充前 limit 个缺失值。

downcast :字典,用于向下转换数据类型。例如,可以将 float64 转换为 float32 。

python 复制代码
import pandas as pd
import numpy as np

# 创建一个包含缺失值的 Series
s = pd.Series([1, np.nan, 3, np.nan, 5])
print(f"初始数组:\n{s}")

# 使用标量值填充
filled_with_scalar = s.fillna(0)
print(f"\n使用标量值填充:\n{filled_with_scalar}")

# 使用字典填充 -- 字典的键要属于标签(显式声明类型转换)
# 先把 Series 转成 object 类型,让 Pandas 明确知道要容纳混合类型
# 否则会报错:Pandas4Warning: 'ndarray' is not supported as a fill value for float64 dtype. In a future version, calling fillna with an incompatible value will raise. Explicitly cast to a common dtype before filling.
s = s.astype('object')
filled_with_dict = s.fillna({1:2,3:"a"})
print(f"\n使用字典填充:\n{filled_with_dict}")

# 使用前向填充
filled_with_ffill = s.ffill()
print(f"\n使用向前填充:\n{filled_with_ffill}")

# 使用后向填充
filled_with_bfill = s.bfill()
print(f"\n使用向后填充:\n{filled_with_bfill}")

# 使用 limit 参数
filled_with_limit = s.fillna(value=0, limit=1)
print(f"\n使用 limit 参数:\n{filled_with_limit}")

运行结果:

复制代码
初始数组:
0    1.0
1    NaN
2    3.0
3    NaN
4    5.0
dtype: float64

使用标量值填充:
0    1.0
1    0.0
2    3.0
3    0.0
4    5.0
dtype: float64

使用字典填充:
0    1.0
1      2
2    3.0
3      a
4    5.0
dtype: object

使用向前填充:
0    1.0
1    1.0
2    3.0
3    3.0
4    5.0
dtype: object

使用向后填充:
0    1.0
1    3.0
2    3.0
3    5.0
4    5.0
dtype: object

使用 limit 参数:
0    1.0
1      0
2    3.0
3    NaN
4    5.0
dtype: object

isnull():检测 Series 对象中的缺失值,它会返回一个布尔型 Series,其中每个元素表示原 Series 对应位置的值是否为缺失值(NaN)。

Series.isnull()

python 复制代码
import pandas as pd
import numpy as np

# 创建一个包含缺失值的Series
s = pd.Series([1, 2, np.nan, 4, np.nan])
print(f"初始化:\n{s}")

# 使用isnull()方法检测缺失值
missing_values = s.isnull()

# 输出结果
print(f"\nisnull():\n{missing_values}")

运行结果:

复制代码
初始化:
0    1.0
1    2.0
2    NaN
3    4.0
4    NaN
dtype: float64

isnull():
0    False
1    False
2     True
3    False
4     True
dtype: bool

drop_duplicates():用于去除 Series 对象中的重复项。

Series.drop_duplicates(keep='first', inplace=False, ignore_index=False)

keep:可选参数,决定了如何处理重复项。有三个选项:

  • 'first' :默认值,保留第一次出现的重复项。
  • 'last' :保留最后一次出现的重复项。
  • False :不保留任何重复项,即删除所有重复项。

inplace :布尔值,默认为 False 。如果设置为 True ,则直接在原始Series上进行操作,返回值 为 None 。如果设置为 False ,则返回一个新的Series,不修改原始Series。

ignore_index :布尔值,默认为 False 。如果设置为 True ,则结果的索引将被重新设置,以反 映删除重复项后的新顺序。如果设置为 False ,则保留原始索引。

python 复制代码
import pandas as pd

series = pd.Series(['a', 'b', 'b', 'c', 'c', 'c', 'd'])
print(f"初始数组:\n{series}")

print("\n保留第一个:")
series_unique = series.drop_duplicates(keep='first')
print(series_unique)

print("\n保留最后一个:")
series_unique = series.drop_duplicates(keep='last')
print(series_unique)

print("\n不保留:")
series_unique = series.drop_duplicates(keep=False)
print(series_unique)

运行结果:

复制代码
初始数组:
0    a
1    b
2    b
3    c
4    c
5    c
6    d
dtype: str

保留第一个:
0    a
1    b
3    c
6    d
dtype: str

保留最后一个:
0    a
2    b
5    c
6    d
dtype: str

不保留:
0    a
6    d
dtype: str

(2)数据转换

replace():替换特定的值、一系列值或者使用字典映射进行替换。

Series.replace(to_replace=None, value=None, inplace=False, limit=None, regex=False, method='pad')

to_replace :要替换的值,可以是以下类型:

  • 标量:单个值。
  • 列表:一系列值。
  • 字典:键是要替换的值,值是替换后的新值。
  • 正则表达式:如果 regex=True ,则可以使用正则表达式匹配要替换的值。

value :替换后的新值,可以是标量或字典。如果 to_replace 是列表,则 value 也应该是相同 长度的列表。

inplace :布尔值,表示是否在原地修改数据。如果为 True ,则直接在原 Series 上修改,不 返回新的对象。

limit :整数,表示最大替换量。如果指定,则只替换前 limit 个匹配的值。

regex :布尔值,表示是否将 to_replace 解释为正则表达式。

method :字符串,表示填充的方法,在 to_replace 参数是一个标量、列表或元组,同时 value 参数设置为 None 时,可以使用 method 参数来指定填充缺失值(NaN)的方式。可选值包括:

  • pad / ffill :用前一个非缺失值去填充缺失值。
  • bfill :用后一个非缺失值去填充缺失值。
python 复制代码
import pandas as pd

# 创建一个 Series
s = pd.Series([1, 2, 3, 4, 5])

# 进行替换操作
replaced = s.replace(to_replace=2, value=20)
print(replaced)

astype():用于将 Series 的数据类型(dtype)转换或转换为另一种类型。

Series.astype(dtype, copy=True, errors='raise')

dtype:你希望将 Series 转换成的数据类型。

copy:布尔值,默认为 True 。如果为 False ,则转换数据类型时不会复制底层数据(如果可能 的话)。

errors:默认为 'raise',控制当转换失败时的行为。如果设置为 'raise',则在转换失败时会抛出异 常;如果设置为 'ignore',转换失败后则返回原始 Series ,不做任何修改。

python 复制代码
import pandas as pd

s = pd.Series([1, 2, 3, 4, 5])

# 将整数转换为字符串
s_str = s.astype(float)
print(s_str)

s = pd.Series(["a","b","c"])

# 将字符串转换为整数 -- ignore 忽略错误,返回原数据;raise 抛出错误
s_int = s_str.astype(int,errors="ignore")
print(s_int)

transform():用于对 Series 中的数据进行转换操作,并返回与原始 Series 具有相同索引的新 Series

Series.transform(func, axis=0, *args, **kwargs)

func : 应用于Series的函数。这个函数可以是内置函数,或者自定义的函数。

axis : 对于Series来说,这个参数不起作用,因为Series是一维的。在DataFrame上使用时, axis=0 (默认)表示按列应用函数, axis=1 表示按行应用函数。

*args, **kwargs : 这些参数会被传递给 func 函数。

python 复制代码
import pandas as pd

# 自定义一个函数,返回每个元素的平方
def square(x, y):
    print(y)
    return x ** 2

# 创建一个Series
s = pd.Series([1, 2, 3, 4, 5])

# 使用自定义函数对Series进行平方变换
transformed_series = s.transform(square,y="yyy")

print(transformed_series)

运行结果:

复制代码
yyy
yyy
yyy
yyy
yyy
0     1
1     4
2     9
3    16
4    25
dtype: int64

(3)数据排序

sort_values():按照值对 Series 进行排序

Series.sort_values(axis=0, ascending=True, inplace=False, kind='quicksort', na_position='last', ignore_index=False, key=None)

axis:默认为 0。对于 Series,这个参数不起作用,因为 Series 是一维的,而 sort_values 总是 在 axis=0 上操作。

ascending:布尔值,默认为 True 。如果是 True ,则按照升序排列;如果是 False ,则按照降序排列。

inplace:布尔值,默认为 False 。如果为 True ,则排序将直接在原始 Series 上进行,不返回新的 Series。

kind:排序算法,{'quicksort', 'mergesort', 'heapsort', 'stable'},默认为 'quicksort'。决定了使用的排序算法。

na_position:{'first', 'last'},默认为 'last'。这决定了 NaN 值的放置位置。

ignore_index:布尔值,默认为 False 。如果为 True ,则排序后的 Series 将重置索引,使其成为默认的整数索引。

key:函数,默认为 None 。如果指定,则这个函数将在排序之前应用于每个值,并且排序将基于这些函数返回的值。

python 复制代码
import pandas as pd
import numpy as np

def square(x):
    return x**2

s = pd.Series([-3, 1, 4, 1, np.nan, 9],index=['a', 'b', 'c', 'd', 'e', 'f'])
print(f"初始数组:\n{s}")

# 排序并重置索引,默认升序,NaN 值放最后
sorted_s = s.sort_values()
print(f"\n按照值升序排序:\n{sorted_s}")

sorted_s = s.sort_values(ascending=False,na_position='first')   # first为字符串,要加引号
print(f"\n按照值降序排序,NaN 值放开头:\n{sorted_s}")

sorted_s = s.sort_values(ignore_index=True,key=square)
print(f"\n重置索引,以函数square的返回值升序排序:\n{sorted_s}")

运行结果:

复制代码
初始数组:
a   -3.0
b    1.0
c    4.0
d    1.0
e    NaN
f    9.0
dtype: float64

按照值升序排序:
a   -3.0
b    1.0
d    1.0
c    4.0
f    9.0
e    NaN
dtype: float64

按照值降序排序,NaN 值放开头:
e    NaN
f    9.0
c    4.0
b    1.0
d    1.0
a   -3.0
dtype: float64

重置索引,以函数square的返回值升序排序:
0    1.0
1    1.0
2   -3.0
3    4.0
4    9.0
5    NaN
dtype: float64

sort_index():按照索引的顺序对数据进行排序。

Series.sort_index(axis=0, level=None, ascending=True, inplace=False, kind='quicksort', na_position='last', sort_remaining=True, ignore_index=False, key=None)

axis : 默认为0,对于 Series,这个参数不起作用。

level : 默认为 None,如果索引是多级索引(也称为层次化索引或 MultiIndex),则可以指定要排序的级别。

ascending : 默认为 True,如果为 True,则按升序排序;如果为 False,则按降序排序。对于多级索引,可以传递一个布尔值列表,以指定每个级别的排序顺序。

inplace : 默认为 False,如果为 True,则直接在原对象上进行修改,不会返回一个新的对象。

kind : {'quicksort', 'mergesort', 'heapsort'},默认为 'quicksort',指定排序算法。'quicksort' 是最快的通用排序算法,但不是稳定的;'mergesort' 是稳定的,但可能比 'quicksort' 慢;'heapsort' 是原地排序算法,但通常比其他两个选项慢。

na_position : {'first', 'last'}, 默认为 'last',指定 NaN 值应该排在排序结果的开头还是结尾。

sort_remaining : 默认为 True,对于多级索引,如果为 True,在该level排序后,在排序的基础上对剩下的级别的元素还会排序。

ignore_index : 默认为 False,如果为 True,则排序后的结果将不再保留原始索引,而是使用默认的整数索引。

key:函数,默认为 None 。如果指定,则这个函数将在排序之前应用于每个值,并且排序将基于这些函数返回的值。

python 复制代码
import numpy as np
import pandas as pd

arrays = [np.array(['qux', 'qux', 'foo', 'foo','baz', 'baz', 'bar', 'bar']),
          np.array(['two', 'one', 'two', 'one','two', 'one', 'two', 'one'])
         ]

# 默认:指定要排序的级别为 0,升序排序
s = pd.Series([1,2,3,4,5,6,7,8],index=arrays)
print(s)
print(s.shape)

# 指定要排序的级别为 1,升序排序,保留其他级别的顺序,不重置索引
res = s.sort_index(level=1,ascending=True,sort_remaining=True,ignore_index=False)
# res = s.sort_index()
print(res)

(4)数据筛选

可以使用一个布尔数组来选择满足条件的元素。

python 复制代码
import pandas as pd

# 创建一个带有标签的Series
series = pd.Series([10, 20, 30, 40, 50], index=['a', 'b', 'c', 'd', 'e'])

# 选择大于30的元素
print(series[series > 30])

(5)数据拼接

concat():用于将多个Pandas对象(如Series或DataFrame)沿着一个轴连接起来的函数。

pandas.concat(objs, *, axis=0, join='outer', ignore_index=False, keys=None, levels=None, names=None, verify_integrity=False, sort=False, copy=None)

objs : 参与连接的Pandas对象的列表或元组。例如,可以是多个Series或DataFrame。

axis : {0或'index', 1或'columns'},表示连接的轴,默认为0。0表示沿着行方向连接(索引轴), 1表示沿着列方向连接(列轴)。

join : {'inner', 'outer'},默认为'outer'。如何处理其他轴上的索引。'outer'表示并集,保留所有索引;'inner'表示交集,只保留所有对象共有的索引。

ignore_index : 布尔值,默认为False。如果为True,则不保留原索引,而是创建一个新索引,可以避免重复的索引。

keys : 序列,默认为None。用于创建分层索引的键。如果提供了keys,则生成的DataFrame 或 Series将具有分层索引。

levels : 序列列表,默认为None。用于构造分层索引的特定级别,如果设置了keys,则默认为 keys。

names : 列表,默认为None。生成的分层索引中的级别名称。如果提供了keys,表示使用keys作为索引名称。

verify_integrity : 布尔值,默认为False。如果为True,则检查新连接的轴是否包含重复的索引,如果发现重复,则引发ValueError。这在确保数据没有重复时很有用。

sort : 布尔值,默认为False。在连接之前是否对非连接轴上的索引进行排序。这在连接多个 DataFrame 时很有用,可以确保索引是有序的。

copy : 布尔值,默认为None。如果为True,则不管是否需要,都会复制数据。如果为False,则尽量避免复制数据,除非必要。None表示自动选择。

python 复制代码
import pandas as pd

# 创建三个Series
s1 = pd.Series([1, 2, 3], index=['a', 'b', 'c'])
s2 = pd.Series([4, 5, 6], index=['c', 'd', 'f'])
s3 = pd.Series([7, 8, 9], index=['e', 'f', 'g'])

# 使用concat连接Series
# 默认按行拼接,并集,保留所有索引,保留原索引,
result = pd.concat([s1, s2, s3])
print(result)

5. 统计计算

(1)count

用于计算 Series 中非 NaN(非空)值的数量

python 复制代码
import pandas as pd

# 创建一个包含空值的Series
s = pd.Series([1, 2, None, 4, None])

# 使用count()函数计算非空值的数量
count_non_na = s.count()
print(count_non_na)

(2)sum

sum() 函数会计算所有值的总和

Series.sum(axis=None, skipna=True, numeric_only=None, min_count=0)

axis : 对于 Series 对象来说,这个参数通常不起作用,因为 Series 是一维的。它主要在 DataFrame 对象中用于指定操作的轴(0表示按列求和,1表示按行求和)

skipna : 布尔值,默认为 True 。如果为 True ,则在计算总和时会忽略 NaN 值,如果为False,则返回NaN

numeric_only : 布尔值,默认为 None 。如果为 True ,则只对数字类型的数据进行计算,只针对 DataFrame

min_count : int值,默认为0。表示在计算总和之前,至少需要多少个非 NaN 值。如果非 NaN 值的数量小于 min_count ,则结果为 NaN

python 复制代码
import pandas as pd

s = pd.Series([1, 2, None, 4, 5])
total = s.sum(min_count=3)  # 至少要 5 个非空值才计算总和
print(total)
total = s.sum(skipna=False)  # 算总和时是否会忽略 NaN 值,默认忽略,若不忽略则返回 nan
print(total)

(3)mean

mean() 函数会计算所有值的平均值

Series.mean(axis=None, skipna=True, numeric_only=None)

axis : 对于 Series 对象来说,这个参数通常不起作用,因为 Series 是一维的。它主要在 DataFrame 对象中用于指定操作的轴(0表示按列计算平均值,1表示按行计算平均值)。

skipna : 布尔值,默认为 True 。如果为 True ,则在计算平均值时会忽略 NaN 值,如果为False, 则返回NaN。

numeric_only : 布尔值,默认为 None 。如果为 True ,则只对数字类型的数据进行计算,只针对 DataFrame。

python 复制代码
# 计算所有值的平均值

import pandas as pd

s = pd.Series([1, 2, 3, None, 4, 5])

# 默认忽略空值
average = s.mean()
print(average)

# 不忽略空值,直接返回 nan
average = s.mean(skipna=False)
print(average)

(4)median

median() 函数用于计算 DataFrame 或 Series 中的中位数

Series.median(axis=0, skipna=True, numeric_only=False)

axis : 对于 Series 对象来说,这个参数通常不起作用,因为 Series 是一维的。它主要在 DataFrame 对象中用于指定操作的轴(0表示按列计算中位数,1表示按行计算中位数)。

skipna : 布尔值,默认为True。如果为True,则在计算中位数之前会排除NaN值,如果为False, 则返回NaN。

numeric_only : 布尔值,默认为 None 。如果为 True ,则只对数字类型的数据进行计算,只针对 DataFrame。

python 复制代码
import pandas as pd

s = pd.Series([1, 2, 3, 4, 5])
median_value = s.median()
print(median_value)

(5)min和max

Series.min() 函数用于计算 Series 对象中的最小值, Series.max() 函数用于计算 Series 对象中的最大值。

Series.min(axis=0, skipna=True, numeric_only=False)

Series.max(axis=0, skipna=True, numeric_only=False)

axis : 对于 Series 对象来说,这个参数通常不起作用,因为 Series 是一维的。它主要在 DataFrame 对象中用于指定操作的轴(0表示按列计算最小值或最大值,1表示按行计算最小值或 最大值)。

skipna : 布尔值,默认为True。如果为True,则在计算最值之前会排除NaN值,如果为False,则返回NaN。

numeric_only : 布尔值,默认为 None 。如果为 True ,则只对数字类型的数据进行计算,只针对 DataFrame。

python 复制代码
import pandas as pd

s = pd.Series([1, 2, 3, 4, 5])

min_value = s.min()
max_value = s.max()

print('最小值是:', min_value)
print('最大值是:', max_value)

(6)var

Series.var() 函数用于计算 Series 对象的方差。

axis : 对于 Series 对象,这个参数不会产生任何效果,因为 Series 是一维的。在 DataFrame 中, axis 用于指定沿着哪个轴计算方差。

skipna : 布尔值,默认为 True 。如果为 True ,则在计算方差之前会忽略 NaN 值。如果设置为 False ,计算方差时会包括 NaN 值,通常会导致结果也是 NaN 。

ddof : 整数,默认为 1 。Delta Degrees of Freedom,用于贝塞尔校正,以得到样本方差的估计。对于无偏估计(样本方差), ddof 通常设置为 1 。如果计算总体方差,应该将 ddof 设置为 0 。

numeric_only : 布尔值,默认为 False 。如果为 True ,则只对数字类型的数据进行方差计算,忽 略非数字类型的数据。

python 复制代码
import pandas as pd
import numpy as np

s = pd.Series([1, 2, np.nan, 4, 5])

# ddof:贝塞尔校正,以得到样本方差的估计(默认为 1)
# 对于无偏估计(样本方差), ddof 通常设置为 1 ;如果计算总体方差,应该将 ddof 设置为 0
variance = s.var()

print('方差是:', variance)

(7)std

Series.std() 函数用于计算 Series 对象的标准差。

Series.std(axis=None, skipna=True, ddof=1, numeric_only=False, **kwargs)

axis : 对于Series来说,这个参数不会产生任何效果,因为Series是一维的。它主要用于 DataFrame,以指定沿着哪个轴计算标准差。

skipna : 布尔值,默认为True。如果为True,则在计算标准差之前会忽略NaN值,如果为False, 则返回NaN。

ddof : 整数,默认为1。Delta Degrees of Freedom,是贝塞尔校正的参数。对于无偏估计(样本 标准差),ddof通常设置为1。

numeric_only : 布尔值,默认为False。如果为True,则只对数字类型的数据进行计算,只针对 DataFrame。

**kwargs : 其他关键字参数。

python 复制代码
import pandas as pd
import numpy as np

s = pd.Series([1, 2, np.nan, 4, 5])
std_dev = s.std()
print('标准差是:', std_dev)

(8)quantile

Series.quantile() 方法用于计算 Series 中数值的分位数。

Series.quantile(q=0.5, interpolation='linear')

q :这个参数是必需的,它表示要计算的分位数值。可以是单一的数值,也可以是一个数值列表。 例如, q=0.5 表示计算中位数(50%分位数)。

interpolation :这个参数决定了当所需的分位数位于两个数据点之间时,应该如何插值。默认 值是 'linear' ,表示线性插值。其他选项包括 'nearest' (最近的值)、 'lower' (选择较小 的值)、 'higher' (选择较大的值)、 'midpoint' (两个值的中间点)。

其计算过程为:

  • 首先将Series中的所有非NaN元素按升序排序。

  • 假设Series的长度为 n, 我们需要计算第 q 个分位数的位置下标 index:

\\\text{index} = q \\times (n - 1) \\

  • 如果 index 是一个整数, 则直接取该位置上的值; 如果 index 不是整数, 则需要进行插值计算。

  • 根据不同的插值方法, 确定最终的分位数值:

    • linear (默认): 线性插值。假设 index = i + f, 其中 i 是整数部分, f 是小数部分。那么分位数为: \(Q = x_{i} + f \times (x_{i+1} - x_{i})\), 其中 \(x_{i}\) 和 \(x_{i+1}\) 是排序后的数据中第 i 和 i+1 个元素。

    • lower: 选择较小的那个值。即取 \(x_{i}\)。

    • higher: 选择较大的那个值。即取 \(x_{i+1}\)。

    • nearest: 选择最近的那个值。如果 f <= 0.5, 取 \(x_{i}\), 否则取 \(x_{i+1}\)。

    • midpoint: 取这两个值的平均数, 即: \(Q = \frac{x_{i} + x_{i+1}}{2}\)。

python 复制代码
import pandas as pd

# 创建一个示例Series
s = pd.Series([1, 2, 3, 4, 5])

# 计算0.5(中位数)分位数 -- q是必须的
median_value = s.quantile(q=0.5, interpolation='linear')

print(median_value)

(9)cummax

该方法用于计算 Series 中元素的累积最大值

返回一个相同长度的Series,其中每个位置上的值表示从Series开始到当前位置(包括当前位置)的最大值。

Series.cummax(axis=None, skipna=True, *args, **kwargs)

axis: 对于Series来说,这个参数不起作用,因为Series是一维的。在DataFrame上使用时,axis=0(默认)表示按列计算,axis=1表示按行计算。

skipna: 布尔值,默认为True。如果为True,则在计算累积最大值时会忽略NaN值;如果为False,则任何NaN值都会传播,并且会导致结果在该位置及之后的值都为NaN。

*args, **kwargs: 这些参数用于兼容性,通常不需要使用。

python 复制代码
import pandas as pd

# 创建一个Series
s = pd.Series([2, 1, 3, 5, 4, 6])

# 计算累积最大值 -- 默认忽略 NaN 值
cummax_series = s.cummax()

print(cummax_series)

运行结果:

复制代码
0    2
1    2
2    3
3    5
4    5
5    6
dtype: int64

(10)cummin

该方法用于计算 Series 中元素的累积最小值

返回一个相同长度的Series,其中每个位置上的值表示从Series开始到当前位置(包括当前位置)的最小值。

Series.cummin(axis=None, skipna=True, *args, **kwargs)

axis: 对于Series来说,这个参数不起作用,因为Series是一维的。在DataFrame上使用时,axis=0(默认)表示按列计算,axis=1表示按行计算。

skipna: 布尔值,默认为True。如果为True,则在计算累积最小值时会忽略NaN值;如果为False,则任何NaN值都会传播,并且会导致结果在该位置及之后的值都为NaN。

*args, **kwargs: 这些参数用于兼容性,通常不需要使用。

python 复制代码
import pandas as pd

# 创建一个Series
s = pd.Series([2, 1, 3, 5, 4, 6])

# 计算累积最小值 -- 默认忽略 NaN 值
cummin_series = s.cummin()

print(cummin_series)

运行结果:

复制代码
0    2
1    1
2    1
3    1
4    1
5    1
dtype: int64

(11)cumsum

用于计算 Series 中元素的累积和

该方法返回一个相同长度的Series,其中每个位置上的值表示从Series开始到当前位置(包括当前位置)的所有元素的累加和。

Series.cumsum(axis=None, skipna=True, *args, **kwargs)

axis: 对于Series来说,这个参数不起作用,因为Series是一维的。在DataFrame上使用时,axis=0(默认)表示按列计算,axis=1表示按行计算。

skipna: 布尔值,默认为True。如果为True,则在计算累积和时会忽略NaN值;如果为False,则任何NaN值都会传播,并且会导致结果在该位置及之后的值都为NaN。

*args, **kwargs: 这些参数用于兼容性,通常不需要使用。

python 复制代码
import pandas as pd
import numpy as np

# 创建一个Series
s = pd.Series([1, 2, np.nan, 4, 5])

# 计算累积和 -- 默认忽略 NaN 值
cumsum_series = s.cumsum()

print(cumsum_series)

运行结果:

复制代码
0     1.0
1     3.0
2     NaN
3     7.0
4    12.0
dtype: float64

(12)cumprod

用于计算 Series 中元素的累积乘积

该方法返回一个相同长度的Series,其中每个位置上的值表示从Series开始到当前位置(包括当前位置)的所有元素的累积乘积。

Series.cumprod(axis=None, skipna=True, *args, **kwargs)

axis: 对于Series来说,这个参数不起作用,因为Series是一维的。在DataFrame上使用时,axis=0(默认)表示按列计算,axis=1表示按行计算。

skipna: 布尔值,默认为True。如果为True,则在计算累积乘积时会忽略NaN值;如果为False,则任何NaN值都会导致结果在该位置及之后的值都为NaN。

*args, **kwargs: 这些参数用于兼容性,通常不需要使用。

python 复制代码
import pandas as pd
import numpy as np

# 创建一个Series
s = pd.Series([1, 2, np.nan, 4, 5])

# 计算累积乘积 -- 默认忽略 NaN 值
cumprod_series = s.cumprod()

print(cumprod_series)

6. 分组和聚合

(1)groupby

用于将 Series 中的数据分组,并允许你对这些分组进行操作,比如计算每个组的总和、平均值、最大值、最小值等。

Series.groupby(by=None, axis=0, level=None, as_index=True, sort=True, group_keys=True, observed=False, dropna=True)

by:确定分组依据,如果by是一个函数,它会在对象索引的每个值上调用。如果传递了字典或Series,将使用这些对象的值来确定组。如果传递了长度等于所选轴的列表或ndarray,则直接使用这些值来确定组。

axis:用于分组的轴。对于Series,这个参数通常设置为0(默认值),因为Series是一维数据结构。

level:如果索引是多级索引(MultiIndex),则此参数用于指定分组所依据的级别,by和level同时只能存在一个,且必须存在一个。

as_index:是否将分组键作为结果的索引,默认值为True。仅与DataFrame输入相关。

sort:是否对结果进行排序。默认值为True。

group_keys:是否在结果中包含分组键。默认值为True。

observed:是否仅包含实际观察到的分类值。默认值为False。

dropna:是否从结果中排除包含NaN的组。默认值为True。

使用原始 series 对象的值分组:

python 复制代码
import pandas as pd

# 创建一个Series对象
data = [10, 20, 10, 30, 20, 10]
series = pd.Series(data)

# 根据Series的值进行分组
grouped = series.groupby(series)
print(grouped)  # 会返回一个对象
print(list(grouped))    # 返回具体的分组情况,有几个分组就有几个数组

# 计算每组的计数
grouped = series.groupby(series).count()
print(grouped)  # 返回每个分组的计数情况

运行结果:

复制代码
<pandas.api.typing.SeriesGroupBy object at 0x000001A2FD9B3950>

[(10, 0    10
2    10
5    10
dtype: int64), (20, 1    20
4    20
dtype: int64), (30, 3    30
dtype: int64)]

10    3
20    2
30    1
dtype: int64

使用 series 对象的索引进行分组:

python 复制代码
import pandas as pd

# 创建一个Series对象
data = [10, 20, 30, 40, 50, 60]
index = ['a', 'b', 'a', 'b', 'c', 'c']
series = pd.Series(data, index=index)

# 根据Series的索引进行分组
grouped = series.groupby(series.index)
print(grouped)
print(list(grouped))

# 计算每组的和
grouped = series.groupby(series.index).sum()
print(grouped)

运行结果:

复制代码
<pandas.api.typing.SeriesGroupBy object at 0x000001A2FB9F7650>

[('a', a    10
a    30
dtype: int64), ('b', b    20
b    40
dtype: int64), ('c', c    50
c    60
dtype: int64)]

a     40
b     60
c    110
dtype: int64

使用 series 的多层索引进行分组(不能同时指定level和by,会报错):

python 复制代码
import pandas as pd
import numpy as np

arrays = [np.array(['qux', 'qux', 'foo', 'foo', 'baz', 'baz', 'bar', 'bar']),
          np.array(['two', 'one', 'two', 'one', 'two', 'one', 'two', 'one'])]

s = pd.Series([1, 2, 3, 4, 5, 6, 7, 8], index=arrays)
print(s)

# 按照arrays[0]分组
res = s.groupby(level=0)
print(res)
print(list(res))

# 按照arrays[0]分组,并求每个分组的平均值
res = s.groupby(level=1).mean()
print(res)

运行结果:

复制代码
qux  two    1
     one    2
foo  two    3
     one    4
baz  two    5
     one    6
bar  two    7
     one    8
dtype: int64

<pandas.api.typing.SeriesGroupBy object at 0x000001A2FD9F1B50>

[('bar', bar  two    7
     one    8
dtype: int64), ('baz', baz  two    5
     one    6
dtype: int64), ('foo', foo  two    3
     one    4
dtype: int64), ('qux', qux  two    1
     one    2
dtype: int64)]

one    5.0
two    4.0
dtype: float64

(2)agg

Series.agg()方法用于对 Series 中的数据进行聚合操作

Series.agg(func=None, axis=0, *args, **kwargs)

func: 聚合函数或函数列表/字典。可以是一个函数名称(字符串),也可以是实际的函数对象,或者是这些的列表或字典。如果是字典,则键将是输出列的名称,值应该是应用于Series的函数。

axis: 整数或字符串,默认为0。由于Series是一维数据结构,这个参数实际上在Series的上下文中不起作用。在DataFrame的上下文中,axis=0表示按列进行聚合,axis=1表示按行进行聚合。

*args: 位置参数,可以传递给func。

**kwargs: 关键字参数,可以传递给func。

python 复制代码
import pandas as pd

s = pd.Series([1, 2, 3, 4, 5])

# 计算平均值
print("平均值:")
result = s.agg('mean')
print(result)

# 计算最大值和最小值
print("\n最大值、最小值:")
result = s.agg(['max', 'min'])
print(result)

# 使用字典为聚合函数命名
# 键:自定义的输出标签名;值:聚合函数
# 结果是一个 Series,索引为 'Maximum'、'Minimum',值为对应聚合结果
print("\n使用字典为聚合函数命名:")
result = s.agg({'Maximum': 'max', 'Minimum': 'min'})
print(result)

# 使用自定义函数并传递额外的参数
def custom_agg(x, power):
    return (x ** power).sum()
def custom_agg2(y,power2):
    return (y + power2).mean()
print("\n自定义聚合函数1 一个函数:")
result = s.agg(custom_agg, power=2)
print(result)
print("\n自定义聚合函数2 多个函数:")
result = s.agg([lambda x: custom_agg(x, power=2),
                lambda y: custom_agg2(y, power2=5)])
print(result)
print("\n自定义聚合函数3 多个函数并自定义索引名称:")
result = s.agg({
    'custom_agg': lambda x: custom_agg(x, power=2),
    'custom_agg2': lambda y: custom_agg2(y, power2=5),
})
print(result)

运行结果:

复制代码
平均值:
3.0

最大值、最小值:
max    5
min    1
dtype: int64

使用字典为聚合函数命名:
Maximum    5
Minimum    1
dtype: int64

自定义聚合函数1 一个函数:
55

自定义聚合函数2 多个函数:
<lambda>    55.0
<lambda>     8.0
dtype: float64

自定义聚合函数3 多个函数并自定义索引名称:
custom_agg     55.0
custom_agg2     8.0
dtype: float64

7. 数据可视化

(1)plot

Series.plot 方法是用来绘制 Series 数据的可视化图表的,该方法提供了灵活的接口,允许用户通过不同的参数来定制图表的类型、样式、布局等,其用法与Matplotlib中的plot相同。

Series.plot(*args, **kwargs)

主要参数:

kind: 图表类型,可以是以下之一:

  • 'line': 折线图(默认)
  • 'bar': 柱状图
  • 'barh': 水平柱状图
  • 'hist': 直方图
  • 'box': 箱线图
  • 'kde': 核密度估计图
  • 'area': 面积图
  • 'pie': 饼图
  • 'scatter': 散点图
  • 'hexbin': 六边形箱图

ax: Matplotlib 轴对象,用于在指定的轴上绘制图表。如果不提供,则创建新的轴对象。

figsize: 图表的尺寸,格式为 (width, height),单位为英寸。

use_index: 是否使用 Series 的索引作为 x 轴标签。默认为 True。

title: 图表的标题。

grid: 是否显示网格线。默认为 False。

legend: 是否显示图例。默认为 False。

xticks: x 轴的刻度位置。

yticks: y 轴的刻度位置。

xlim: x 轴的范围,格式为 (min, max)。

ylim: y 轴的范围,格式为 (min, max)。

color: 绘制颜色,可以是单个颜色或颜色列表。

label: 图例标签。

python 复制代码
import pandas as pd
import matplotlib.pyplot as plt

s = pd.Series([1, 3, 2, 4, 5], index=['a', 'b', 'c', 'd', 'e'])
s.plot(kind='line',  # 折线
       title='Line Plot',   # 标题
       grid=True,    # 显示网格线
       figsize=(8, 4),      # 画板大小
       style='r--',  # 颜色+虚线
       linewidth=2,  # 线宽
       label='test', # 图例标签
       legend=True,  # 显示图例
       )
plt.show()

(2)hist

用于绘制 Series 数据直方图的方法。这个方法提供了多种参数来定制直方图的外观和样式。

Series.hist(by=None, ax=None, grid=True, xlabelsize=None, xrot=None, ylabelsize=None, yrot=None, figsize=None, bins=10, backend=None, legend=False, **kwargs)

by:如果不是None,则将数据分组并分别绘制每个组的直方图。

ax: matplotlib的Axes对象,如果指定了,则直方图将绘制在该Axes上。

grid: 布尔值,默认为True,表示是否在直方图上显示网格线。

xlabelsize: int或str,用于设置x轴标签的字体大小。

xrot: int或float,用于设置x轴标签的旋转角度。

ylabelsize: int或str,用于设置y轴标签的字体大小。

yrot: int或float,用于设置y轴标签的旋转角度。

figsize: 元组,用于设置直方图的大小,格式为 (width, height)。

bins: int或序列,用于设置直方图的柱子数量或具体的边界。

backend: 用于指定绘图后端,通常 Pandas 会使用 matplotlib。

legend: 布尔值,默认为 False,表示是否在直方图上显示图例。

**kwargs: 其他关键字参数,将被传递给 matplotlib 的 hist 函数。

python 复制代码
import pandas as pd
import numpy as np
from matplotlib import pyplot as plt

# 创建一个包含随机数据的Series
s = pd.Series(np.random.randn(1000))

# 绘制直方图 -- 默认不分组(by=None)
s.hist(bins=30,     # 设置直方图的柱子数量或具体的边界(int或序列)
       figsize=(8, 6),      # 直方图的大小
       color='blue',    # 柱子填充颜色
       edgecolor='black'    # 柱子边缘颜色
       )

# 设置标题和轴标签
plt.title('Histogram of a Random Sample')
plt.xlabel('Value')
plt.ylabel('Frequency')

# 显示图表
plt.show()

8. 其他常用方法

(1)unique

该函数用于返回 Series 中的唯一值。这个方法返回一个数组,其中包含了Series中所有唯一的值。数组中的值是按照它们在原始Series中首次出现的顺序排列的。

Series.unique()

python 复制代码
import pandas as pd

# 创建一个Series
s = pd.Series(['apple', 'banana', 'apple', 'orange', 'banana', 'banana'])

# 获取唯一值
unique_values = s.unique()

# 输出唯一值
print(unique_values)
print(type(unique_values))

运行结果:

复制代码
<StringArray>
['apple', 'banana', 'orange']
Length: 3, dtype: str

<class 'pandas.arrays.StringArray'>

(2)nunique

该函数用于计算Series中唯一值的数量。这个方法返回一个整数,表示Series中唯一值的数量。

Series.nunique(dropna=True)

dropna:布尔值,默认为True。如果为True,则在计算唯一值数量之前,会先从Series中排除NaN值

python 复制代码
import pandas as pd

# 创建一个Series
s = pd.Series(['apple', 'banana', 'apple', 'orange', 'banana', 'banana'])

# 计算唯一值的数量(排除NaN)
unique_count = s.nunique(dropna=True)

# 输出唯一值的数量
print(unique_count)

(3)value_counts

该方法用于计算Series中每个值的出现次数。这个方法返回一个包含每个唯一值及其对应出现次数的Series。

Series.value_counts(normalize=False, sort=True, ascending=False, bins=None, dropna=True)

  • normalize:布尔值(True / False)
    默认为 False,返回计数;如果为 True,返回相对频率,相对频率基于参与计数(未被 dropna 排除)的值的总数
  • sort:布尔值,是否按频率排序
    默认为 True,结果按计数值(频率)降序排序
    若为 False, 则不按频率排序,保留数据在原始 Series 中首次出现的顺序
  • ascending:布尔值,只在 sort=True 时才有意义,判断升序还是降序
    默认为 False,结果按计数值降序排序;为 True,结果按计数值升序排序
  • bins:用于离散化连续数据,可以是整数或分位数数组。如果指定了 bins,则结果将是每个 bin(箱子) 的计数
  • dropna:布尔值,默认为 True,排除 NaN 值
python 复制代码
import pandas as pd
import numpy as np

# 创建一个Series
s = pd.Series(['apple', 'banana', 'apple', 'orange', np.nan, 'banana', 'banana'])

# 返回相对频率
value_frequency = s.value_counts(normalize=True)
print(f"参与计数的值:\n{value_frequency}")

value_frequency = s.value_counts(normalize=True, dropna=False)
print(f"\n所有值,包括nan:\n{value_frequency}")


# 计算每个值的出现次数 -- 默认:sort=true(要排序),ascending=false(降序)
value_counts = s.value_counts()
# 输出每个值的出现次数
print(f"\n按照频率降序排序:\n{value_counts}")

# 计算每个值的出现次数 -- 修改:sort=true(要排序),ascending=true(升序)
value_counts = s.value_counts(ascending=True)
# 输出每个值的出现次数
print(f"\n按照频率升序排序:\n{value_counts}")

# 计算每个值的出现次数 -- 修改:sort=false(不排序)
value_counts = s.value_counts(sort=False)
# 输出每个值的出现次数
print(f"\n不按照频率排序,按照首次出现的顺序输出:\n{value_counts}")

# 离散化连续数据 -- 只能用于数值类型的数据,字符串不行
s = pd.Series([12, 15, 18, 20, 25, 28, 30, 35, 40, 45])
value_discrete = s.value_counts(bins=5) # 分5组,每个区间差为(45-12)/5=6.6
print(f"\n离散化连续数据:\n{value_discrete}")

运行结果:

复制代码
参与计数的值:
banana    0.500000
apple     0.333333
orange    0.166667
Name: proportion, dtype: float64

所有值,包括nan:
banana    0.428571
apple     0.285714
orange    0.142857
NaN       0.142857
Name: proportion, dtype: float64

按照频率降序排序:
banana    3
apple     2
orange    1
Name: count, dtype: int64

按照频率升序排序:
orange    1
apple     2
banana    3
Name: count, dtype: int64

不按照频率排序,按照首次出现的顺序输出:
apple     2
banana    3
orange    1
Name: count, dtype: int64

离散化连续数据:
(11.966000000000001, 18.6]    3
(18.6, 25.2]                  2
(25.2, 31.8]                  2
(38.4, 45.0]                  2
(31.8, 38.4]                  1
Name: count, dtype: int64

(4)describe

该方法用于生成描述性统计信息。这个方法返回一个包含计数、均值、标准差、最小值、25%分位数、中位数、75%分位数和最大值的 Series。

Series.describe(percentiles=None, include=None, exclude=None)

  • percentiles:数值列表或数值元组,默认为 [.25, .5, .75],表示要包含在输出中的分位数。
  • include:字符串或类型列表,用于指定要包括在结果中的数据类型。默认为 None,即包括所有数字类型。
  • exclude:字符串或类型列表,用于指定要从结果中排除的数据类型。默认为 None。
python 复制代码
import pandas as pd

# 创建一个Series
s = pd.Series([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])

# 生成描述性统计信息
description = s.describe()

# 输出描述性统计信息
print(description)

运行结果:

复制代码
count    10.00000
mean      5.50000
std       3.02765
min       1.00000
25%       3.25000
50%       5.50000
75%       7.75000
max      10.00000
dtype: float64

(5)copy

该函数用于创建Series对象的一个副本。

Series.copy(deep=True)

  • deep:布尔值,默认为True。
    当deep=True时,会进行深拷贝,即复制数据和索引的副本,而不是仅仅复制引用
    当deep=False时,会进行浅拷贝,即只复制数据或索引的引用。
python 复制代码
import pandas as pd

# 创建一个Series
original_series = pd.Series([1, 2, 3, 4, 5])

# 创建一个深拷贝 -- 复制底层数据,修改副本不会影响原数据
deep_copied_series = original_series.copy()

# 创建一个浅拷贝 -- 不立即复制底层数据
# Pandas 3.0 及以上默认采用写时复制,修改副本不会影响原数据
# Pandas 3.0 以下未启用写时复制时,修改一方通常会影响另一方
shallow_copied_series = original_series.copy(deep=False)

# 修改深拷贝中的数据
deep_copied_series[0] = 999

# 输出原始Series和深拷贝后的Series
print(f"Original Series:\n{original_series}")
print(f"Deep Copied Series:\n{deep_copied_series}")

# 修改浅拷贝中的数据
shallow_copied_series[1] = 888

# 输出原始Series和浅拷贝后的Series -- 不会修改原数据
print(f"Original Series after shallow_copied_series):\n{original_series}")
print(f"Shallow Copied Series:\n{shallow_copied_series}")

(6)reset_index

该函数用于重置Series的索引,将原来的索引转换为一个列,并将一个新的默认整数索引赋给Series。

Series.reset_index(level=None, *, drop=False, name=no_default, inplace=False, allow_duplicates=False)

  • level:int 或 level 名,可选
    如果 Series 是多级索引 (MultiIndex),则只移除指定的级别
    默认为 None,移除所有级别
  • drop:布尔值,默认为False
    如果为True,则不将旧索引添加为新列,直接丢弃
  • name:字符串,可选
    用于新列的名称,默认为 no_default
    如果未指定,并且索引有名字,则使用索引的名字
  • inplace:布尔值,默认为False
    如果为True,则在原地修改 Series,不返回新的对象
    该参数自3.1.0版本起已废弃:该关键字已被弃用,将在pandas 4.0中彻底移除
  • allow_duplicates:布尔值,默认为False
    如果为True,则允许在重置索引后出现重复的索引值
    默认情况下,如果出现重复的索引值,Pandas 会抛出错误,对 Series 无用
python 复制代码
import pandas as pd
import numpy as np

# 创建一个简单的Series对象
data = pd.Series(np.random.randint(1, 100, 5), index=['c', 'a', 'e', 'b', 'd'])
print("排序前:")
print(data)

# 对Series进行排序 -- 按照值排序
sorted_series = data.sort_values()
print("\n排序后的Series: ")
print(sorted_series)

# 重置索引
reset_indexed_series = sorted_series.reset_index()
print("\n重置索引后的Series: ")
print(reset_indexed_series)

reset_indexed_series = sorted_series.reset_index(drop=True)
print("\n重置索引后的Series -- 丢弃旧索引: ")
print(reset_indexed_series)

reset_indexed_series = sorted_series.reset_index(name='new')
print("\n重置索引后的Series -- 指定新列的名称: ")
print(reset_indexed_series)



# 验证 allow_duplicates=True:允许新生成的列名与现有列名重复
s = pd.Series([10, 20, 30], index=pd.Index(['a', 'b', 'c'], name='index'))
s.name = 'index'

print(f"\n原始 Series:\n{s}")
print("\n允许重复列名:")
print(s.reset_index(allow_duplicates=True))
print("\n不允许重复列名:抛出 ValueError")
# print(s.reset_index(allow_duplicates=False))    # 由于新生成的索引列与原数据列名称冲突,会抛出 ValueError

运行结果:

复制代码
排序前:
c    16
a    51
e    77
b    18
d    36
dtype: int32

排序后的Series: 
c    16
b    18
d    36
a    51
e    77
dtype: int32

重置索引后的Series: 
  index   0
0     c  16
1     b  18
2     d  36
3     a  51
4     e  77

重置索引后的Series -- 丢弃旧索引: 
0    16
1    18
2    36
3    51
4    77
dtype: int32

重置索引后的Series -- 指定新列的名称: 
  index  new
0     c   16
1     b   18
2     d   36
3     a   51
4     e   77

原始 Series:
index
a    10
b    20
c    30
Name: index, dtype: int64

允许重复列名:
  index  index
0     a     10
1     b     20
2     c     30

不允许重复列名:抛出 ValueError

(7)info

用于显示Series的概要信息的方法。这个方法提供了关于Series的元数据,包括数据类型、非空值的数量、内存使用情况等。

Series.info(verbose=None, buf=None, max_cols=None, memory_usage=None, show_counts=True)

  • verbose:布尔值或None,默认为None。如果为True,则输出更详细的信息。
  • buf:一个文件-like对象,如果提供,则将输出写入这个对象而不是标准输出。
  • max_cols:int,用于显示的最大列数。如果列数超过这个值,则显示"..."。
  • memory_usage:布尔值或str,默认为None。如果为True,则显示内存使用情况。如果设置为deep,则会计算列的内存使用情况,这可能非常慢。
  • show_counts:布尔值,默认为True。如果为True,则显示非空值的数量。
python 复制代码
import numpy as np
import pandas as pd

# 创建一个示例Series
s = pd.Series([1, 2, np.nan, 4, 5], name='example_series', index=['a', 'b', 'c', 'd', 'e'])

# 显示Series的概要信息
s.info()

运行结果:

复制代码
<class 'pandas.Series'>
Index: 5 entries, a to e
Series name: example_series
Non-Null Count  Dtype  
--------------  -----  
4 non-null      float64
dtypes: float64(1)
memory usage: 80.0+ bytes

(8)apply

对 Series 中的每个元素应用一个函数,并返回一个结果 Series。

Series.apply(func, convert_dtype=True, args=(), **kwargs)

  • func:一个函数,它将被应用到Series的每一个元素上。这个函数可以是Python的内置函数,也可以是用户自定义的函数。
  • convert_dtype:布尔值,默认为True。如果为True,则在可能的情况下,Pandas 会尝试将结果转换为适合的数据类型。
  • args:一个元组,包含传递给func的位置参数。
  • **kwargs:一个字典,包含传递给func的关键字参数。
python 复制代码
import pandas as pd

# 创建一个series
series = pd.Series([1, 2, 3, 4, 5])

# 使用apply方法结合lambda函数,对series中的每个元素执行平方操作
res = series.apply(lambda x: x * 2)

# 打印结果,输出每个元素的平方值
print(res)

(9)map

对series中的每个元素应用一个映射,它允许你将一个函数应用到series的每个元素上,或者将一个字典或series映射到series的值上。

Series.map(arg, na_action=None)

  • arg:这可以是以下几种类型:
    • 函数:将此函数应用于series的每个元素。
    • 字典:将series中的值映射到字典的键上,返回对应的值。
    • Series:使用另一个series的索引来映射当前series的值。
  • na_action:默认为 None。如果设置为 'ignore',并且 arg 是一个函数,那么将忽略 NaN 值,并保留它们不变。

将一个函数应用到series的每个元素上:

python 复制代码
import pandas as pd

# 创建一个series
s = pd.Series([1, 2, 3, 4, 5])

# 定义一个函数,用于将值翻倍
def double(x):
    return x * 2

# 使用map方法应用这个函数
s_doubled = s.map(double)
print(s_doubled)

将一个字典应用到 series 的每个元素上:

python 复制代码
import pandas as pd

# 创建一个映射字典
grade_mapping = {
    90: 'A',
    80: 'B',
    70: 'C',
    60: 'D',
    0: 'F'
}

# 创建一个成绩的Series
grades = pd.Series([80, 92, 77, 60, 100])

# 使用map方法应用这个字典
grades_mapped = grades.map(grade_mapping)
print(grades_mapped)

将一个 Series 对象应用到 series 的每个元素上:

python 复制代码
import pandas as pd

# 创建一个名为series1的Series对象
series1 = pd.Series([50, 60, 70, 80, 90], index=['a', 'b', 'c', 'd', 'e'])

# 创建一个名为grades的Series对象,代表成绩数据
grades = pd.Series([80, 92, 'c', 59, 100], index=[0, 1, 2, 3, 4])

# 使用grades的map方法,会把 grades 中的每个值当作 series1 的索引标签(键)进行查找,而不是当作 series1 中的数据值进行查找
res = grades.map(series1)

# 打印输出新生成的Series对象res
print(res)

运行结果:

复制代码
0     NaN
1     NaN
2    70.0
3     NaN
4     NaN
dtype: float64

(三)二维数组 DataFrame

二维数组则是可以理解为excel表格:

1. DataFrame的创建

在 Pandas 中,使用 DataFrame 来创建二维数组 DataFrame:

class pandas.DataFrame(data=None, index=None, columns=None, dtype=None,copy=None)

  • data :数据源,可以是以下几种形式:
    • 列表,其中每个元素是一行数据
    • 字典,其中键是列名,值是列值(列表或数组)
    • 2d-Ndarray
    • Series 对象,每个 Series 成为一列。
  • index :行标签,如果没有指定,默认是整数索引 [0, ..., n-1] ,其中 n 是数据中的行数
  • columns :列标签,如果没有指定,则列标签从数据源中推断
  • dtype :指定某列的数据类型。如果指定,则所有列都将转换为指定的数据类型
  • copy :布尔值,默认为 None 。如果为 True ,则复制数据;如果为 False ,则尽可能避免复制数据

(1)使用列表创建

初始列表:

python 复制代码
import pandas as pd

# 创建一个包含学生信息的列表,每个元素代表一个学生的姓名
data_list = ['小明', '小红', '小刚']

#定义列名
columns = ['姓名']

#使用 pandas 库创建一个 DataFrame,将数据列表和列名作为参数传入
df = pd.DataFrame(data_list, columns=columns)

#打印 DataFrame 以查看数据
print(df)

运行结果:

复制代码
   姓名
0  小明
1  小红
2  小刚

嵌套列表:

python 复制代码
import pandas as pd

# 创建一个包含学生信息的嵌套列表,每个子列表代表一个学生的姓名、年龄和成绩
data_list = [
    ['小明', 20, 85],
    ['小红', 18, 90],
    ['小刚', 22, 88]
]

# 定义列名,分别对应姓名、年龄和成绩
columns = ['姓名', '年龄', '成绩']

# 使用 pandas 库创建一个 DataFrame,将数据列表和列名作为参数传入
df = pd.DataFrame(data_list, columns=columns)

# 打印 DataFrame 以查看数据
print(df)

运行结果:

复制代码
   姓名  年龄  成绩
0  小明  20  85
1  小红  18  90
2  小刚  22  88

(2)使用字典创建

可以使用一个字典来创建 DataFrame

其中字典的键将作为列名,字典的值可以是列表、数组等可迭代对象

它们的长度要一致,代表每一列的数据。

字典中指定了列名,就不要单独指定列标签

python 复制代码
import pandas as pd

# 定义一个字典,其中包含两组数据:姓名和年龄
data = {
    'Name': ['Tom', 'Nick', 'John'],  # 'Name' 键对应一个包含姓名的列
    'Age': [20, 21, 19]               # 'Age' 键对应一个包含年龄的列
}

# 使用 pd.DataFrame() 函数将字典转换为 DataFrame 对象
# data 字典中的键自动成为 DataFrame 的列名,值成为列的数据
df = pd.DataFrame(data)

# 打印 DataFrame 对象,查看其内容
print(df)

运行结果:

复制代码
   Name  Age
0   Tom   20
1  Nick   21
2  John   19

(3)使用Ndarray数组创建

python 复制代码
import pandas as pd
import numpy as np

# 定义一个二维 Ndarray 数组,其中包含两组数据:姓名和年龄
data_array = np.array([
    ['Tom', 20],
    ['Nick', 21],
    ['John', 19]
])

# 使用 pd.DataFrame() 函数将二维数组转换为 DataFrame 对象
df = pd.DataFrame(data_array, columns=['Name', 'Age'])

# 打印
print(df)

运行结果:

复制代码
   Name Age
0   Tom  20
1  Nick  21
2  John  19

(4)使用Series创建

如果有多个 Series 对象,也可以将它们组合成一个 DataFrame

python 复制代码
import pandas as pd

# 创建三个 pandas Series 对象
s1 = pd.Series(['小明', '小红', '小刚'], name='姓名')
s2 = pd.Series([20, 18, 22, 0], name='年龄')
s3 = pd.Series([85, 90, 88], name='成绩')

# 将 Series 对象组合成一个字典,键是 series 的名称,值是 Series 本身
# 然后将这个字典传递给 DataFrame 构造函数来创建一个 DataFrame
df = pd.DataFrame({s1.name: s1, s2.name: s2, s3.name: s3})

# 打印 DataFrame 对象,查看其内容
print(df)

运行结果:

复制代码
    姓名  年龄    成绩
0   小明  20  85.0
1   小红  18  90.0
2   小刚  22  88.0
3  NaN   0   NaN
python 复制代码
import pandas as pd

# 创建三个 pandas Series 对象
s1 = pd.Series(['小明', '小红', '小刚'], name='姓名')
s2 = pd.Series([20, 18, 22, 0], name='年龄')
s3 = pd.Series([85, 90, 88], name='成绩')

# 使用 concat 拼接,并指定轴为 1
df = pd.concat([s1, s2, s3], axis=1)

# 打印 DataFrame 对象,查看其内容
print(df)

运行结果:

复制代码
    姓名  年龄    成绩
0   小明  20  85.0
1   小红  18  90.0
2   小刚  22  88.0
3  NaN   0   NaN

2. DataFrame的属性

(1)index

返回 DataFrame 的行索引

python 复制代码
import pandas as pd

# 定义字典数据,包含姓名、年龄和成绩三个字段
data = {
    '姓名': ['小明', '小红', '小刚'],
    '年龄': [20, 18, 22],
    '成绩': [85, 90, 88]
}

# 将字典转换为 DataFrame,并自定义行索引为 'a', 'b', 'c'
df = pd.DataFrame(data, index=['a', 'b', 'c'])

# 打印输出的 DataFrame 数据
print(df)


# ========== 1. 返回 DataFrame 的行索引 ==========
print("\n行索引 -- \n",df.index)

(2)columns

返回 DataFrame 的列名

python 复制代码
import pandas as pd

# 定义字典数据,包含姓名、年龄和成绩三个字段
data = {
    '姓名': ['小明', '小红', '小刚'],
    '年龄': [20, 18, 22],
    '成绩': [85, 90, 88]
}

# 将字典转换为 DataFrame,并自定义行索引为 'a', 'b', 'c'
df = pd.DataFrame(data, index=['a', 'b', 'c'])

# 打印输出的 DataFrame 数据
print(df)

# ========== 2. 返回 DataFrame 的列名 ==========
print("\n列名 -- \n",df.columns)

(3)values

返回 DataFrame 中数据的 Ndarray 表示

python 复制代码
import pandas as pd

# 定义字典数据,包含姓名、年龄和成绩三个字段
data = {
    '姓名': ['小明', '小红', '小刚'],
    '年龄': [20, 18, 22],
    '成绩': [85, 90, 88]
}

# 将字典转换为 DataFrame,并自定义行索引为 'a', 'b', 'c'
df = pd.DataFrame(data, index=['a', 'b', 'c'])

# 打印输出的 DataFrame 数据
print(df)

# ========== 3. 返回 DataFrame 中数据的 Ndarray 表示 ==========
print("\nNdarray(矩阵)表示 -- \n",df.values)

(4)dtypes

返回每列的数据类型,没有 dtype 属性

python 复制代码
import pandas as pd

# 定义字典数据,包含姓名、年龄和成绩三个字段
data = {
    '姓名': ['小明', '小红', '小刚'],
    '年龄': [20, 18, 22],
    '成绩': [85, 90, 88]
}

# 将字典转换为 DataFrame,并自定义行索引为 'a', 'b', 'c'
df = pd.DataFrame(data, index=['a', 'b', 'c'])

# 打印输出的 DataFrame 数据
print(df)

# ========== 4. 返回每列的数据类型 ==========
print("\n每列的数据类型 -- \n",df.dtypes)

(5)shape

返回 DataFrame 的形状(行数,列数)

python 复制代码
import pandas as pd

# 定义字典数据,包含姓名、年龄和成绩三个字段
data = {
    '姓名': ['小明', '小红', '小刚'],
    '年龄': [20, 18, 22],
    '成绩': [85, 90, 88]
}

# 将字典转换为 DataFrame,并自定义行索引为 'a', 'b', 'c'
df = pd.DataFrame(data, index=['a', 'b', 'c'])

# 打印输出的 DataFrame 数据
print(df)

# ========== 5. 返回  DataFrame 的形状(行数,列数) ==========
print("\n形状(行数,列数) -- \n",df.shape)

(6)size

返回 DataFrame 中的元素数量

python 复制代码
import pandas as pd

# 定义字典数据,包含姓名、年龄和成绩三个字段
data = {
    '姓名': ['小明', '小红', '小刚'],
    '年龄': [20, 18, 22],
    '成绩': [85, 90, 88]
}

# 将字典转换为 DataFrame,并自定义行索引为 'a', 'b', 'c'
df = pd.DataFrame(data, index=['a', 'b', 'c'])

# 打印输出的 DataFrame 数据
print(df)

# ========== 6. 返回 DataFrame 中的元素数量 ==========
print("\n元素数量 -- \n",df.size)

(7)empty

返回 DataFrame 是否为空

python 复制代码
import pandas as pd

# 定义字典数据,包含姓名、年龄和成绩三个字段
data = {
    '姓名': ['小明', '小红', '小刚'],
    '年龄': [20, 18, 22],
    '成绩': [85, 90, 88]
}

# 将字典转换为 DataFrame,并自定义行索引为 'a', 'b', 'c'
df = pd.DataFrame(data, index=['a', 'b', 'c'])

# 打印输出的 DataFrame 数据
print(df)

# ========== 7. 返回  DataFrame  是否为空 ==========
print("\n是否为空 -- \n",df.empty)

(8)T

返回 DataFrame 的转置

python 复制代码
import pandas as pd

# 定义字典数据,包含姓名、年龄和成绩三个字段
data = {
    '姓名': ['小明', '小红', '小刚'],
    '年龄': [20, 18, 22],
    '成绩': [85, 90, 88]
}

# 将字典转换为 DataFrame,并自定义行索引为 'a', 'b', 'c'
df = pd.DataFrame(data, index=['a', 'b', 'c'])

# 打印输出的 DataFrame 数据
print(df)

# ========== 8. 返回 DataFrame 的转置 ==========
res = df.T
print("\n转置 -- \n",res)

(9)axes

返回行轴和列轴的列表

python 复制代码
import pandas as pd

# 定义字典数据,包含姓名、年龄和成绩三个字段
data = {
    '姓名': ['小明', '小红', '小刚'],
    '年龄': [20, 18, 22],
    '成绩': [85, 90, 88]
}

# 将字典转换为 DataFrame,并自定义行索引为 'a', 'b', 'c'
df = pd.DataFrame(data, index=['a', 'b', 'c'])

# 打印输出的 DataFrame 数据
print(df)

# ========== 9. 返回行轴和列轴的列表 ==========
print("\n行轴和列轴的列表 -- \n",df.axes)
print("\n存储的元数据 -- \n",df.attrs)

(10)ndim

返回 DataFrame 的维度数。对于标准的二维 DataFrame,这个值通常是 2

python 复制代码
import pandas as pd

# 定义字典数据,包含姓名、年龄和成绩三个字段
data = {
    '姓名': ['小明', '小红', '小刚'],
    '年龄': [20, 18, 22],
    '成绩': [85, 90, 88]
}

# 将字典转换为 DataFrame,并自定义行索引为 'a', 'b', 'c'
df = pd.DataFrame(data, index=['a', 'b', 'c'])

# 打印输出的 DataFrame 数据
print(df)

# ========== 10. 返回 DataFrame 的维度数 ==========
print("\n维度数 -- \n",df.ndim)

(11)attrs

允许用户存储DataFrame的元数据,它是一个字典,可以用来存储任意与DataFrame相关的额外信息

python 复制代码
import pandas as pd

# 定义字典数据,包含姓名、年龄和成绩三个字段
data = {
    '姓名': ['小明', '小红', '小刚'],
    '年龄': [20, 18, 22],
    '成绩': [85, 90, 88]
}

# 将字典转换为 DataFrame,并自定义行索引为 'a', 'b', 'c'
df = pd.DataFrame(data, index=['a', 'b', 'c'])

# 打印输出的 DataFrame 数据
print(df)

# ========== 11. 允许用户存储DataFrame的元数据 ==========
# 是一个字典,可以用来存储任意与DataFrame相关的额外信息
df.attrs['creator'] = 'clover'
df.attrs['created_at'] = '2026-10-26'
print("\n存储的元数据 -- \n",df.attrs)

(12)运行结果

复制代码
   姓名  年龄  成绩
a  小明  20  85
b  小红  18  90
c  小刚  22  88

行索引 -- 
 Index(['a', 'b', 'c'], dtype='str')

列名 -- 
 Index(['姓名', '年龄', '成绩'], dtype='str')

Ndarray(矩阵)表示 -- 
 [['小明' 20 85]
 ['小红' 18 90]
 ['小刚' 22 88]]

每列的数据类型 -- 
 姓名      str
年龄    int64
成绩    int64
dtype: object

形状(行数,列数) -- 
 (3, 3)

元素数量 -- 
 9

是否为空 -- 
 False

转置 -- 
      a   b   c
姓名  小明  小红  小刚
年龄  20  18  22
成绩  85  90  88

行轴和列轴的列表 -- 
 [Index(['a', 'b', 'c'], dtype='str'), Index(['姓名', '年龄', '成绩'], dtype='str')]

维度数 -- 
 2

存储的元数据 -- 
 {'creator': 'clover', 'created_at': '2026-10-26'}

3. DataFrame中元素的索引与访问

(1)使用列名访问

对于 DataFrame 来说,可以直接使用列名来访问某一列的数据,返回的是一个Series对象

python 复制代码
import pandas as pd

data = {
    '姓名': ['小明', '小红', '小刚'],
    '年龄': [20, 18, 22],
    '成绩': [85, 90, 88]
}

df = pd.DataFrame(data)

print("访问完整数据:")
print(df)

print("\n访问列名为'姓名'的列:")
print(df['姓名'])

print("\n访问列名为'姓名'和'年龄'的列:")
print(df[['姓名', '年龄']])

(2)loc和iloc

可以使用 loc 与 iloc 属性访问单个或多个数据,其语法为:

df.loc[row_label, column_label]

  • loc:根据标签(Label)选择数据
  • iloc:根据整数位置(Integer Location)选择数据
python 复制代码
import pandas as pd

data = {
    '姓名': ['小明', '小红', '小刚'],
    '年龄': [20, 18, 22],
    '成绩': [85, 90, 88]
}

df = pd.DataFrame(data)

print("访问完整数据:")
print(df)

print("\n访问【第 1 行,'姓名'列】的数据:")
print(df.loc[0, '姓名'])

print("\n访问【第 0 到 2 行,'姓名'到'成绩'列】的数据:")
print(df.loc[0:2, '姓名':'成绩'])

print("\n访问【第 0 行,第 0 列】的数据:")
print(df.iloc[0, 0])

print("\n访问【第 0 到 1 行,第 0 到 1 列】的数据:")
print(df.iloc[0:1, 0:1])

(3)at和iat

使用 at 和 iat 属性来访问单个数据

  • at:根据行标签和列标签,访问单个值
  • iat:根据行位置和列位置,访问单个值
python 复制代码
import pandas as pd

data = {
    '姓名': ['小明', '小红', '小刚'],
    '年龄': [20, 18, 22],
    '成绩': [85, 90, 88]
}

df = pd.DataFrame(data)

print("访问完整数据:")
print(df)

print("\n访问【第 0 行,'姓名'列】的数据:")
print(df.at[0, '姓名'])

print("\n访问【第 0 行,第 0 列】的数据:")
print(df.iat[0, 0])

(4)head

该方法用于获取 DataFrame 的前 n 行。默认情况下,如果不指定 n 的值,它会返回前 5 行

DataFrame.head(n=5)

  • n :整数,表示要返回的行数。默认值为5
python 复制代码
import pandas as pd

# 创建一个示例 DataFrame
data = {
    'A': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
    'B': [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
}
df = pd.DataFrame(data)

# 使用 head 方法获取前 5 行
print(df.head())

(5)tail

该方法用于获取 DataFrame 的最后 n 行。与 DataFrame.head 方法类似,如果不指定 n 的值,它会默认返回最后 5 行

DataFrame.tail(n=5)

  • n :整数,表示要返回的行数。默认值为5
python 复制代码
import pandas as pd

# 创建一个示例 DataFrame
data = {
    'A': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
    'B': [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
}
df = pd.DataFrame(data)

# 使用 tail 方法获取最后5行
print(df.tail())

(6)isin

DataFrame.isin(values) 方法用于检查 DataFrame 中的元素是否包含在指定的集合 values 中。这个方法会返回一个布尔型 DataFrame,其中的每个元素都表示原始DataFrame 中对应元素是否在 values 中

DataFrame.isin(values)

  • values :可以是单个值、列表、元组、集合或另一个DataFrame / Series。如果 values 是一个字典,键是列名,值是列表或元组,表示该列中要检查的值
python 复制代码
import pandas as pd

# 创建一个示例DataFrame
data = {
    'A': [1, 2, 3, 4, 5],
    'B': ['a', 'b', 'c', 'd', 'e']
}
df = pd.DataFrame(data)

# 检查 DataFrame 中的元素是否包含在指定的值集合中
values_to_check = [2, 4, 'c']
print(df.isin(values_to_check))

运行结果:

复制代码
       A      B
0  False  False
1   True  False
2  False   True
3   True  False
4  False  False

(7)get

用于从 DataFrame 中获取列,它类似于直接使用 df[key] 来访问列,但是当列不存在时, get 方法提供了一个更安全的方式来处理这种情况,你可以指定一个默认值,而不是引发一个错误

DataFrame.get(key, default=None)

  • key :你想获取的列的名称
  • default :如果列不存在时返回的默认值。默认是 None 。
python 复制代码
import pandas as pd

data = {
    '姓名': ['小明', '小红', '小刚'],
    '年龄': [20, 18, 22],
    '成绩': [85, 90, 88]
}

df = pd.DataFrame(data)

# 获取'成绩'列
scores = df.get('成绩')

# 尝试获取不存在的列,返回指定值
non_existent_column = df.get('体重', default='Not Found')

print(scores)
print(non_existent_column)

4. 数据操作

(1)数据清洗

isnull()

用于检测 DataFrame 中的缺失值,它会返回一个相同形状的布尔型 DataFrame,其中每个元素表示原始 DataFrame 中相应位置的元素是否是缺失值

python 复制代码
import pandas as pd
import numpy as np

# 创建一个包含缺失值的 DataFrame
df = pd.DataFrame({
    'A': [1, 2, np.nan],
    'B': [4, np.nan, 6],
    'C': [7, 8, 9]
})

# 打印原始 DataFrame
print(df)

# 使用 isnull() 方法检测缺失值
missing_values = df.isnull()

print(missing_values)

运行结果:

复制代码
     A    B  C
0  1.0  4.0  7
1  2.0  NaN  8
2  NaN  6.0  9

       A      B      C
0  False  False  False
1  False   True  False
2   True  False  False
dropna()

用于删除 DataFrame 中的缺失值

DataFrame.dropna(axis=0, how=any, thresh=_NoDefault.no_default, subset=None, inplace=False, ignore_index=False)

  • axis:{0 或 'index', 1 或 'columns'},默认为 0。0表示按行删除,1表示按列删除
  • how:{'any', 'all'},默认为 'any'。确定删除缺失值的逻辑:
    • 'any':如果行或列中的任意一个值是 NaN,就删除该行或列
    • 'all':如果行或列中的所有值都是 NaN,才删除该行或列
  • thresh:指定每行或每列至少需要有多少个非缺失值才能保留。如果设置此参数,how 参数将被忽略
  • subset:指定在哪些列中搜索缺失值。如果未指定,则在所有列中搜索
  • inplace:是否修改 DataFrame 而不是创建新的 DataFrame
  • ignore_index:布尔值,默认为 False。如果为 True,则不保留原始 DataFrame 的索引
python 复制代码
import pandas as pd
import numpy as np

# 创建一个包含缺失值的 DataFrame
df = pd.DataFrame({
    'A': [1, 2, np.nan],
    'B': [4, np.nan, 6],
    'C': [7, 8, 9]
})

# 打印原始 DataFrame
print(df)

# 删除任何含有 NaN 值的行
df_cleaned = df.dropna()

print(df_cleaned)

运行结果:

复制代码
     A    B  C
0  1.0  4.0  7
1  2.0  NaN  8
2  NaN  6.0  9

     A    B  C
0  1.0  4.0  7
fillna()

用于填充 DataFrame 中的缺失值

DataFrame.fillna(value=None, *, method=None, axis=0, inplace=False, limit=None)

  • value:填充值,可以是单个值,也可以是字典(对不同的列填充不同的值),或者一个 Series
  • method:{'bfill', 'ffill'},默认为无默认值。指定填充方法:
    • 'bfill' 或 'backfill':使用下一个有效观测值填充
    • 'ffill' 或 'pad':使用前一个有效观测值填充
    • pandas 3.1.0 中没有 method 了,直接 df.bfill() / df.ffill()
  • axis:{0 或 'index', 1 或 'columns'},默认为 0
  • inplace:布尔值,默认为 False。如果为 True,则在原地修改 DataFrame 而不返回新的 DataFrame
  • limit:int,默认为无默认值。如果指定了 method,则该参数限制连续填充的数量
python 复制代码
import pandas as pd
import numpy as np

# 创建一个包含缺失值的 DataFrame
df = pd.DataFrame({
    'A': [1, 2, np.nan],
    'B': [np.nan, np.nan, 6],
    'C': [7, np.nan, 9]
})

# 打印原始 DataFrame
print(df)

# 使用固定值填充缺失值
print("\n固定值填充 -- ")
df_filled_value = df.fillna(value=0)
print(df_filled_value)

# 使用字典填充
print("\n字典填充 -- ")
data = {
    'A': 'a',
    'B': 'b',
    'C': 'c'
}

df_filled_dict = df.fillna(value=data)
print(df_filled_dict)

# 使用 Series 填充
print("\nSeries 填充 -- ")
data_series = pd.Series(['a', 'b', 'c'], ['A', 'B', 'C'])
df_filled_series = df.fillna(value=data_series)
print(df_filled_series)

# 使用前一个有效观测值填充缺失值
print("\n前值填充 -- ")
df_filled_ffill = df.ffill()
print(df_filled_ffill)

# 使用后一个有效观测值填充缺失值
print("\n后值填充 -- ")
df_filled_bfill = df.bfill()
print(df_filled_bfill)

运行结果:

复制代码
     A    B    C
0  1.0  NaN  7.0
1  2.0  NaN  NaN
2  NaN  6.0  9.0

固定值填充 -- 
     A    B    C
0  1.0  0.0  7.0
1  2.0  0.0  0.0
2  0.0  6.0  9.0

字典填充 -- 
     A    B    C
0  1.0    b  7.0
1  2.0    b    c
2    a  6.0  9.0

Series 填充 -- 
     A    B    C
0  1.0    b  7.0
1  2.0    b    c
2    a  6.0  9.0

前值填充 -- 
     A    B    C
0  1.0  NaN  7.0
1  2.0  NaN  7.0
2  2.0  6.0  9.0

后值填充 -- 
     A    B    C
0  1.0  6.0  7.0
1  2.0  6.0  9.0
2  NaN  6.0  9.0
drop_duplicates()

用于删除 DataFrame 中的重复行

DataFrame.drop_duplicates(subset=None, keep='first', inplace=False, ignore_index=False)

  • subset:指定要检查重复的列名或列名列表,默认值为 None,表示检查所有列
  • keep:{'first', 'last', False},默认为 'first'。确定如何处理重复项:
    • 'first':保留第一次出现的重复项
    • 'last':保留最后一次出现的重复项
    • False:删除所有重复项
  • inplace:是否修改 DataFrame 而不是创建新的 DataFrame
  • ignore_index:是否重置索引值
python 复制代码
import pandas as pd

# 创建一个包含重复行的 DataFrame
df = pd.DataFrame({
    'A': [1, 1, 2, 2, 3, 3],
    'B': [1, 1, 2, 2, 3, 3],
    'C': [1, 1, 2, 2, 3, 3]
})

# 打印原始 DataFrame
print(df)

# 删除重复行,保留第一次出现的重复项
print("\n保留第一次出现的重复项 --")
df_dedup_first = df.drop_duplicates()
print(df_dedup_first)

# 根据指定列删除重复行
print("\n指定列删除重复行 --")
df_dedup_column = df.drop_duplicates(subset=['A'])
print(df_dedup_column)

# 删除重复行,保留最后一次出现的重复项
print("\n保留最后一次出现的重复项 --")
df_dedup_last = df.drop_duplicates(keep='last')
print(df_dedup_last)

# 删除所有重复行
print("\n删除所有重复行 --")
df_dedup_all = df.drop_duplicates(keep=False)
print(df_dedup_all)

运行结果:

复制代码
   A  B  C
0  1  1  1
1  1  1  1
2  2  2  2
3  2  2  2
4  3  3  3
5  3  3  3

保留第一次出现的重复项 --
   A  B  C
0  1  1  1
2  2  2  2
4  3  3  3

指定列删除重复行 --
   A  B  C
0  1  1  1
2  2  2  2
4  3  3  3

保留最后一次出现的重复项 --
   A  B  C
1  1  1  1
3  2  2  2
5  3  3  3

删除所有重复行 --
Empty DataFrame
Columns: [A, B, C]
Index: []

(2)数据转换

replace()

用于替换 DataFrame 中的值

DataFrame.replace(to_replace=None, value=_NoDefault.no_default, inplace=False, limit=None, regex=False, method=_NoDefault.no_default)

  • to_replace:被替换的内容,可以是 scalar, list, dict, regex。如果是字典,则键是要替换的值,值是相应的替换值。
  • value:替换后的值。可以是单个值、列表或数组,与 to_replace 长度相同。
  • inplace:是否在原地修改 DataFrame。
  • limit:限制替换的数量。可以是整数,表示最多替换多少个值。
  • regex:是否使用正则表达式进行匹配。默认值为 False。
  • method:替换方法。可以是:
    • 'pad' 或 'ffill':使用前面的数据向后填充。
    • 'backfill' 或 'bfill':使用后面的数据向前填充。
    • pandas 3.1.0 中没有 method 了,直接 df.bfill() / df.ffill()
python 复制代码
import pandas as pd

# 创建一个 DataFrame
df = pd.DataFrame({
    'A': [1, 2, 3, 4, 5],
    'B': ['a', 'b', 'a', 'b', 'a']
})

# 打印原始 DataFrame
print(df)

# 用数字 100 替换所有的 1
df_replaced = df.replace(to_replace=1, value=100)

# 用字符串 'z' 替换所有的 'a'
df_replaced = df_replaced.replace(to_replace='a', value='z')

# 使用字典替换多个值
df_replaced = df.replace({
    2: 200,
    'b': 'y'
})

# 使用正则表达式替换 -- ^a$ 表示:整个字符串必须恰好是一个小写字母 a
df_replaced = df.replace(to_replace=r'^a$', value='z', regex=True)

print(df_replaced)
pivot()

用于改变表格形状格式

DataFrame.pivot(columns, index=typing.Literal[<no_default>], values=typing.Literal[<no_default>])

  • columns:作为新 DataFrame 的行索引的列名。可以是单个列名或列名列表
  • index:作为新 DataFrame 的列标签的列名。可以是单个列名或列名列表
  • values:作为新 DataFrame 的值的列名。可以是单个列名或列名列表
python 复制代码
import pandas as pd

# 创建一个 DataFrame
df = pd.DataFrame({
    'foo': ['one', 'one', 'one', 'two', 'two', 'two'],
    'bar': ['A', 'B', 'C', 'A', 'B', 'C'],
    'baz': [1, 2, 3, 4, 5, 6],
    'zoo': ['x', 'y', 'z', 'q', 'w', 't']
})

# 打印原始 DataFrame
print(df)

# 使用 pivot 方法对 DataFrame 进行重塑,其中 foo 作为行索引,bar 作为列索引,baz 作为值
print("\n")
res1 = df.pivot(index='foo', columns='bar', values='baz')
# 打印重塑后的 DataFrame
print(res1)

# 使用 pivot 方法对 DataFrame 进行重塑,其中 foo 作为行索引,bar 作为列索引,baz、zoo 作为值
print("\n")
res2 = df.pivot(index='foo', columns='bar', values=['baz', 'zoo'])
# 打印重塑后的DataFrame
print(res2)

运行结果:

复制代码
   foo bar  baz zoo
0  one   A    1   x
1  one   B    2   y
2  one   C    3   z
3  two   A    4   q
4  two   B    5   w
5  two   C    6   t


bar  A  B  C
foo         
one  1  2  3
two  4  5  6


    baz       zoo      
bar   A  B  C   A  B  C
foo                    
one   1  2  3   x  y  z
two   4  5  6   q  w  t
melt()

用于改变表格形状格式

DataFrame.melt(id_vars=None, value_vars=None, var_name=None, value_name='value', col_level=None, ignore_index=True)

  • id_vars:保持不变的列名或列名列表
  • value_vars:字符串或字符串列表,可选。要重塑的列名或列名列表。这些列的值将被展平到新的行中
  • var_name:新的列名,该列数据为原来列的名称。默认值为 None,表示使用默认名称(指定的是新生成的列的名字,而这列里面存放的是原来 DataFrame 的列名)
  • value_name:字符串。新的列名,用于存储原来列的值。默认值为 'value'
  • col_level:整数或列标签,可选。如果 DataFrame 的列是多级索引,指定要使用的级别。默认值为 None,表示使用所有级别
  • ignore_index:是否忽略原来的索引,重新生成一个新的默认整数索引。默认值为 True
python 复制代码
import pandas as pd

# 创建一个DataFrame
df = pd.DataFrame({
    'A': {0: 'a', 1: 'b', 2: 'c'},
    'B': {0: 1, 1: 3, 2: 5},
    'C': {0: 2, 1: 4, 2: 6}
})

# 打印原始 DataFrame
print(df)

# 使用 melt 方法对 DataFrame 进行重塑
res1 = df.melt(id_vars=['A'], value_vars=['B'],     # A 列不变,重塑 B 列
               var_name='myVarname', value_name='myValnames'    # 新列名为 myVarname,存储原列名 B;新列名为 myValnames,存储原列 B 中的值
               )

# 打印重塑后的 DataFrame
print(res1)

运行结果:

复制代码
   A  B  C
0  a  1  2
1  b  3  4
2  c  5  6

   A myVarname  myValnames
0  a         B           1
1  b         B           3
2  c         B           5
pivot_table()

用于生成一个指定格式的数据透视表

DataFrame.pivot_table(values=None, index=None, columns=None, aggfunc='mean', fill_value=None, margins=False, dropna=True, margins_name='All', observed=False, sort=True)

  • values:要聚合的列名或列名列表。如果未指定,则使用所有数值列
  • index:作为新 DataFrame 的行索引的列名或列名列表
  • columns:作为新 DataFrame 的列标签的列名或列名列表
  • aggfunc:聚合函数,可以是:
    • 单个函数(如 'mean'、'sum'、'count' 等)
    • 函数列表(如 ['mean', 'sum'])
    • 字典,键是列名,值是聚合函数
  • fill_value:用于填充缺失值的值。默认值为 None
  • margins:是否添加总计行和总计列。默认值为 False
  • dropna:是否从结果中删除包含缺失值的行。默认值为 True
  • margins_name:总计行和总计列的名称。默认值为 'All'
  • observed:是否仅显示已观察到的类别。默认值为 False
  • sort:是否对结果进行排序。默认值为 True
python 复制代码
import numpy as np
import pandas as pd

# 创建一个 DataFrame
df = pd.DataFrame({
    "A": ["foo", "foo", "foo", "foo", "foo",
          "bar", "bar", "bar", "bar"],
    "B": ["one", "one", "one", "two", "two",
          "one", "one", "two", "two"],
    "C": ["small", "large", "large", "small",
          "small", "large", "small", "small",
          "large"],
    "D": [1, 2, 2, 3, 3, 4, 5, 6, 7],
    "E": [2, 4, 5, 5, 6, 6, 8, 9, 9]
})

# 打印原始 DataFrame
print(df)

# 使用 pivot_table 方法创建一个数据透视表
# D为值,AB为行标签,C为列标签,求和
table = df.pivot_table(values='D', index=['A', 'B'], columns=['C'], aggfunc=np.sum)

# 打印数据透视表
print(table)

运行结果:

复制代码
     A    B      C  D  E
0  foo  one  small  1  2
1  foo  one  large  2  4
2  foo  one  large  2  5
3  foo  two  small  3  5
4  foo  two  small  3  6
5  bar  one  large  4  6
6  bar  one  small  5  8
7  bar  two  small  6  9
8  bar  two  large  7  9


C        large  small
A   B                
bar one    4.0    5.0
    two    7.0    6.0
foo one    4.0    1.0
    two    NaN    6.0
astype()

用于转换 DataFrame 中指定列的数据类型

DataFrame.astype(dtype, copy=None, errors='raise')

  • dtype:新的数据类型,可以是字典或数据类型。如果是字典,则键是列名,值是要转换为的数据类型。如果指定为单一数据类型,则所有列都将转换为该类型
  • copy:布尔值,默认为 None。如果为 True,则在转换数据之前创建数据的副本。如果为 False,则尽可能地避免复制,但这可能会影响到输入数据的原始 DataFrame。如果为 None(默认值),则仅在需要时复制数据
  • errors:{'raise', 'ignore'},默认为 'raise'。控制当转换失败时的行为。如果为 'raise',则在无法转换数据时抛出异常;如果为 'ignore',则在无法转换数据时保持原始数据类型不变
python 复制代码
import pandas as pd

# 创建一个示例 DataFrame
df = pd.DataFrame({
    'A': [1, 2, 3],
    'B': [4.5, 5.5, 6.5],
    'C': ['7', '8', '9']
})

# 打印原始 DataFrame
print(df)

# 将列 'A' 转换为浮点数类型
df['A'] = df['A'].astype(float)

# 使用字典将多列转换为不同的数据类型
# 将列 'B' 转换为整数类型,列 'C' 也转换为整数类型
df = df.astype({
    'B': int,
    'C': int
})

# 打印转换后的 DataFrame
print(df)

# 打印 DataFrame 中各列的数据类型
print(df.dtypes)

运行结果:

复制代码
   A    B  C
0  1  4.5  7
1  2  5.5  8
2  3  6.5  9

     A  B  C
0  1.0  4  7
1  2.0  5  8
2  3.0  6  9

A    float64
B      int64
C      int64
dtype: object

(3)数据排序

sort_values()

用于根据一个或多个列的值对 DataFrame 进行排序

DataFrame.sort_values(by, axis=0, ascending=True, inplace=False, kind='quicksort', na_position='last', ignore_index=False, key=None)

  • by:用于排序的列名或列名列表。
  • axis:{0 或 'index', 1 或 'columns'},默认为 0。沿着哪个轴进行排序。
  • ascending:排序的方向,True 表示升序,False 表示降序,默认为 True。
  • inplace:是否在原地修改 DataFrame。
  • kind:{'quicksort', 'mergesort', 'heapsort', 'stable'},默认为 'quicksort'。排序算法。
  • na_position:{'first', 'last'},默认为 'last'。缺失值的放置位置。
  • ignore_index:布尔值,默认为 False。是否忽略原来的索引,重新生成一个新的默认整数索引。
  • key:函数,默认为 None。应用于 by 中每个列的函数,排序将基于函数的返回值。
python 复制代码
import numpy as np
import pandas as pd

# 创建一个示例 DataFrame
df = pd.DataFrame({
    'col1': ['A', 'A', 'B', np.nan, 'D', 'C'],
    'col2': [2, 1, 9, 8, 7, 4],
    'col3': [0, 1, 9, 4, 2, 3],
    'col4': ['a', 'B', 'c', 'D', 'e', 'F']
})

# 打印原始 DataFrame
print(df)

# 根据 'col1' 列对 DataFrame 进行排序
res1 = df.sort_values(by=['col1'])
# 打印排序后的DataFrame
print(res1)

# 根据 'col1' 和 'col2' 列对 DataFrame 进行排序
res2 = df.sort_values(by=['col1', 'col2'])

# 打印排序后的 DataFrame
print(res2)

运行结果:

复制代码
  col1  col2  col3 col4
0    A     2     0    a
1    A     1     1    B
2    B     9     9    c
3  NaN     8     4    D
4    D     7     2    e
5    C     4     3    F

  col1  col2  col3 col4
0    A     2     0    a
1    A     1     1    B
2    B     9     9    c
5    C     4     3    F
4    D     7     2    e
3  NaN     8     4    D

  col1  col2  col3 col4
1    A     1     1    B
0    A     2     0    a
2    B     9     9    c
5    C     4     3    F
4    D     7     2    e
3  NaN     8     4    D
sort_index()

用于根据索引对 DataFrame 进行排序

DataFrame.sort_index(axis=0, level=None, ascending=True, inplace=False, kind='quicksort', na_position='last', sort_remaining=True, ignore_index=False, key=None)

  • axis:{0 或 'index', 1 或 'columns'},默认为 0。表示沿着哪个轴进行排序。0按照行标签排序,1按照列标签排序
  • level:如果索引是多级索引,指定要排序的级别。可以是整数或整数列表
  • ascending:默认为 True。表示排序是升序还是降序
  • inplace:是否在原地修改 DataFrame
  • kind:{'quicksort', 'mergesort', 'heapsort', 'stable'},默认为 'quicksort'。排序算法
  • na_position:{'first', 'last'},默认为 'last'。缺失值的位置放置。
  • sort_remaining:是否对剩余的级别进行排序。仅在多级索引时有效。默认值为 True
  • ignore_index:是否忽略原来的索引,重新生成一个新的默认整数索引。默认值为 False
  • key:函数,默认为 None。应用于索引的函数,排序将基于函数的返回值
python 复制代码
import pandas as pd
import numpy as np

# 创建一个多级索引的 DataFrame
arrays = [np.array(['qux', 'qux', 'foo', 'foo']),
          np.array(['two', 'one', 'two', 'one'])]
df = pd.DataFrame({'A': [1, 2, 3, 4], 'B': [4, 3, 2, 1]}, index=arrays)

print(df)

# 按第一层索引升序排序
df_sorted_by_first_level = df.sort_index(level=0)
print(df_sorted_by_first_level)

# 按第二层索引降序排序
df_sorted_by_second_level_desc = df.sort_index(level=1, ascending=False)
print(df_sorted_by_second_level_desc)

# 按整个索引升序排序
df_sorted_by_full_index = df.sort_index(ascending=True)
print(df_sorted_by_full_index)

运行结果:

复制代码
         A  B
qux two  1  4
    one  2  3
foo two  3  2
    one  4  1
    
         A  B
foo one  4  1
    two  3  2
qux one  2  3
    two  1  4
    
         A  B
qux two  1  4
foo two  3  2
qux one  2  3
foo one  4  1

         A  B
foo one  4  1
    two  3  2
qux one  2  3
    two  1  4

(4)数据筛选

可以使用布尔数组进行索引,选择满足条件的数据

python 复制代码
import pandas as pd

data = {
    '姓名': ['小明', '小红', '小刚'],
    '年龄': [20, 18, 22],
    '成绩': [85, 90, 88]
}

df = pd.DataFrame(data)

# 使用布尔索引选择成绩大于或等于90的学生
high_scores = df[df['成绩'] >= 90]

print(high_scores)

(5)数据拼接

concat()

用于沿一个轴将多个 pandas 对象连接在一起

pandas.concat(objs, axis=0, join='outer', ignore_index=False, keys=None, levels=None, names=None, verify_integrity=False, sort=False, copy=True)

  • objs:要连接的对象列表
  • axis:{0, 1, 'index', 'columns'},默认为 0
  • join:连接方式。可以是:
    • 'outer':取所有索引的并集
    • 'inner':取所有索引的交集
  • ignore_index:是否忽略原来的索引,重新生成一个新的默认整数索引。默认值为 False
  • keys:用于生成多级索引的键列表。每个键对应一个对象
  • levels:用于多级索引的级别列表。通常与 keys 一起使用
  • names:用于多级索引的名称列表。通常与 keys 一起使用
  • verify_integrity:是否验证最终的 DataFrame 是否有重复的索引。默认值为 False
  • sort:是否对结果按照列名进行升序排序。默认值为 False
  • copy:是否复制数据
python 复制代码
import pandas as pd

# 创建两个 DataFrame
df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],
                    'B': ['B0', 'B1', 'B2', 'B3'],
                    'C': ['C0', 'C1', 'C2', 'C3'],
                    'D': ['D0', 'D1', 'D2', 'D3']},
                   index=[0, 1, 2, 3])

df2 = pd.DataFrame({'A': ['A4', 'A5', 'A6', 'A7'],
                    'B': ['B4', 'B5', 'B6', 'B7'],
                    'C': ['C4', 'C5', 'C6', 'C7'],
                    'F': ['F4', 'F5', 'F6', 'F7']},
                   index=[4, 5, 6, 7])

# 沿着竖直方向(按行)拼接两个 DataFrame
result = pd.concat([df1, df2], axis=0, ignore_index=True)

print(result)

运行结果:

复制代码
    A   B   C    D    F
0  A0  B0  C0   D0  NaN
1  A1  B1  C1   D1  NaN
2  A2  B2  C2   D2  NaN
3  A3  B3  C3   D3  NaN
4  A4  B4  C4  NaN   F4
5  A5  B5  C5  NaN   F5
6  A6  B6  C6  NaN   F6
7  A7  B7  C7  NaN   F7
merge()

用于根据一个或多个相同的键将两个 DataFrame 对象连接起来

DataFrame.merge(right, how='inner', on=None, left_on=None, right_on=None, left_index=False, right_index=False, sort=False, suffixes=('_x', '_y'), copy=None, indicator=False, validate=None)

  • right:另一个 DataFrame 对象
  • how:{'left', 'right', 'outer', 'inner', 'cross'},默认为 'inner'。确定连接的类型:
    • 'left':使用左侧(调用 merge 的 DataFrame)的索引进行左连接
    • 'right':使用右侧(参数 right 中的 DataFrame)的索引进行右连接
    • 'outer':使用两个DataFrame的并集连接
    • 'inner':使用两个DataFrame的交集连接
  • on:用于合并的列名。如果 left_on 和 right_on 都没有指定,则使用 on
  • left_on:左侧 DataFrame 中用于合并的列名。不与on同时使用
  • right_on:右侧 DataFrame 中用于合并的列名。不与on同时使用
  • left_index:是否使用左侧 DataFrame 的索引作为合并键。默认值为 False。不与on同时使用
  • right_index:是否使用右侧 DataFrame 的索引作为合并键。默认值为 False。不与on同时使用
  • sort:是否对结果进行排序。默认值为 False
  • suffixes:用于重命名重复列的后缀。默认值为 ('_x', '_y')
  • copy:是否复制数据。默认值为 None,表示根据需要自动决定是否复制
  • indicator:是否添加一个指示器列,显示每行来自哪个 DataFrame。默认值为 False
  • validate:检查合并键。可以是:
    • 'one_to_one':检查合并键在两者中是否唯一
    • 'one_to_many':检查合并键在左侧是否唯一
    • 'many_to_one':检查合并键在右侧是否唯一
    • 'many_to_many':不检查
python 复制代码
import pandas as pd

# 创建两个 DataFrame
df1 = pd.DataFrame({'key': ['A', 'B', 'C', 'D'],
                    'value': [1, 2, 3, 4]}, 
                    index=['a', 'b', 'c', 'd'])
df2 = pd.DataFrame({'key': ['B', 'D', 'D', 'E'],
                    'value': [5, 6, 7, 8]}, 
                    index=['a', 'c', 'e', 'f'])

# 使用内连接(inner join)合并两个 DataFrame
result = df1.merge(df2, on='key', how='inner', suffixes=('_left', '_right'))

print(result)

运行结果:

复制代码
  key  value_left  value_right
0   B           2            5
1   D           4            6
2   D           4            7
join()

用于将两个对象的列连接起来

DataFrame.join(other, on=None, how='left', lsuffix='', rsuffix='', sort=False, validate=None)

  • other:另一个 DataFrame 对象
  • on:用于连接的列名
  • how:{'left', 'right', 'outer', 'inner'},默认为 'left'。确定连接的类型:
    • 'left':使用左侧(调用 join 的 DataFrame)的索引进行左连接
    • 'right':使用右侧(参数 other 中的 DataFrame)的索引进行右连接
    • 'outer':使用两个 DataFrame 的索引的并集进行全外连接
    • 'inner':使用两个 DataFrame 的索引的交集进行内连接
  • lsuffix:用于重命名重复列的左后缀。默认值为空字符串 ''
  • rsuffix:用于重命名重复列的右后缀。默认值为空字符串 ''
  • sort:是否对结果进行排序。默认值为 False
  • validate:检查合并键。可以是:
    • 'one_to_one':检查合并键在两者中是否唯一
    • 'one_to_many':检查合并键在左侧是否唯一
    • 'many_to_one':检查合并键在右侧是否唯一
    • 'many_to_many':不检查
python 复制代码
import pandas as pd

# 创建两个 DataFrame
df1 = pd.DataFrame({'key': ['A', 'B', 'C', 'D'],
                    'value': [1, 2, 3, 4]},
                   index=['k0', 'k1', 'k2', 'k3'])
df2 = pd.DataFrame({'value2': [5, 6, 7, 8]},
                   index=['k1', 'k2', 'k3', 'k4'])

# 使用左连接(left join)根据索引合并两个 DataFrame
result = df1.join(df2, how='left')

print(result)

5. 统计

(1)count

用于计算 DataFrame 中非 NaN 值的数量

DataFrame.count(axis=0, numeric_only=False)

  • axis:{0 或 'index', 1 或 'columns'},决定统计的方向。
    • 如果 axis=0 或 axis='index',则对每列进行计数,返回一个 Series,其索引为列名,值为每列非 NaN 值的数量。
    • 如果 axis=1 或 axis='columns',则对每行进行计数,返回一个 Series,其索引为行索引,值为每行非 NaN 值的数量。
  • numeric_only:是否只计算数值列中的非 NaN 值的数量,忽略非数值列,默认为 False。
python 复制代码
import pandas as pd
import numpy as np

# 创建一个包含 NaN 值的 DataFrame
df = pd.DataFrame({
    'A': [1, 2, np.nan, 4],
    'B': [5, np.nan, np.nan, 8],
    'C': ['foo', 'bar', 'baz', np.nan]
})

# 计算每列非 NaN 值的数量
count_per_column = df.count()
print("Count per column:")
print(count_per_column)

# 计算每行非 NaN 值的数量
count_per_row = df.count(axis='columns')
print("\nCount per row:")
print(count_per_row)

# 只计算数值列的非 NaN 值的数量
count_numeric_only = df.count(numeric_only=True)
print("\nCount numeric only:")
print(count_numeric_only)

运行结果:

复制代码
Count per column:
A    3
B    2
C    3
dtype: int64

Count per row:
0    3
1    2
2    1
3    2
dtype: int64

Count numeric only:
A    3
B    2
dtype: int64

(2)sum

用于计算 DataFrame 中数值的总和

DataFrame.sum(axis=0, skipna=True, numeric_only=False, min_count=0, **kwargs)

以下是从图片中提取的文字,已按照 Markdown 格式排版:

  • axis: {0 或 'index', 1 或 'columns', None},默认为 0。这个参数决定了求和是在哪个轴上进行:
    • 如果 axis=0 或 axis='index',则对每列进行求和,返回一个 Series,其索引为列名,值为每列的总和。
    • 如果 axis=1 或 axis='columns',则对每行进行求和,返回一个 Series,其索引为行索引,值为每行的总和。
  • skipna: 布尔值,默认为 True。如果为 True,则在计算总和时会忽略 NaN 值。
  • numeric_only: 布尔值,默认为 False。如果为 True,则只对数值列进行求和,忽略非数值列。
  • min_count: int,默认为 0。这个参数指定了在计算总和之前,至少需要非 NaN 值的最小数量。如果某个分组中的非 NaN 值的数量小于 min_count,则结果为 NaN。
  • **kwargs: 其他关键字参数。这些参数通常用于兼容性或特殊用途,通常不需要。
python 复制代码
import pandas as pd
import numpy as np

# 创建一个包含 NaN 值的 DataFrame
df = pd.DataFrame({
    'A': [1, 2, np.nan, 4],
    'B': [5, np.nan, np.nan, 8],
    'C': ['foo', 'bar', 'baz', 'qux']
})

# 计算每列的总和
sum_per_column = df.sum()
print("Sum per column:")
print(sum_per_column)

# # 计算每行的总和
# sum_per_row = df.sum(axis='columns')
# print("\nSum per row:")
# print(sum_per_row)  # 报错:'float' and 'str' 不能相加

# 只计算数值列的总和
sum_numeric_only = df.sum(numeric_only=True)
print("\nSum numeric only:")
print(sum_numeric_only)

# 使用 min_count 参数
sum_with_min_count = df.sum(min_count=2)
print("\nSum with min_count=2:")
print(sum_with_min_count)

运行结果:

复制代码
Sum per column:
A             7.0
B            13.0
C    foobarbazqux
dtype: object

Sum numeric only:
A     7.0
B    13.0
dtype: float64

Sum with min_count=2:
A             7.0
B            13.0
C    foobarbazqux
dtype: object

(3)mean

用于计算 DataFrame 中数值的平均值

DataFrame.mean(axis=0, skipna=True, numeric_only=False, **kwargs)

  • axis: {0 或 'index', 1 或 'columns', None},默认为 0。这个参数决定了计算平均值是在哪个轴上进行:
    • 如果 axis=0 或 axis='index',则对每列进行计算,返回一个 Series,其索引为列名,值为每列的平均值。
    • 如果 axis=1 或 axis='columns',则对每行进行计算,返回一个 Series,其索引为行索引,值为每行的平均值。
  • skipna: 布尔值,默认为 True。如果为 True,则在计算平均值时会忽略 NaN 值。
  • numeric_only: 布尔值,默认为 False。如果为 True,则只对数值列进行计算,忽略非数值列。
  • **kwargs: 其他关键字参数。这些参数通常用于兼容性或特殊用途,通常不需要。
python 复制代码
import pandas as pd
import numpy as np

# 创建一个包含 NaN 值的 DataFrame
df = pd.DataFrame({
    'A': [1, 2, np.nan, 4],
    'B': [5, np.nan, np.nan, 8],
    'C': ['foo', 'bar', 'baz', 'qux']  # 非数值列
})

# # 计算每列的平均值
# mean_per_column = df.mean()
# print("Mean per column:")
# print(mean_per_column)  # 数据中有字符串,无法获取结果,会报错
#
# # 计算每行的平均值
# mean_per_row = df.mean(axis='columns')
# print("\nMean per row:")
# print(mean_per_row) # 数据中有字符串,无法获取结果,会报错

# 只计算数值列的平均值
mean_numeric_only = df.mean(numeric_only=True)
print("\nMean numeric only:")
print(mean_numeric_only)

运行结果:

复制代码
Mean numeric only:
A    2.333333
B    6.500000
dtype: float64

(4)median

用于计算 DataFrame 中数值的中位数

DataFrame.median(axis=0, skipna=True, numeric_only=False, **kwargs)

  • axis: {0 或 'index', 1 或 'columns'},默认为 0。这个参数决定了计算中位数是在哪个轴上进行:
    • 如果 axis=0 或 axis='index',则对每列进行计算,返回一个 Series,其索引为列名,值为每列的中位数。
    • 如果 axis=1 或 axis='columns',则对每行进行计算,返回一个 Series,其索引为行索引,值为每行的中位数。
  • skipna: 布尔值,默认为 True。如果为 True,则在计算中位数时会忽略 NaN 值。
  • numeric_only: 布尔值,默认为 False。如果为 True,则只对数值列进行计算,忽略非数值列。
  • **kwargs: 其他关键字参数。这些参数通常用于兼容性或特殊用途,通常不需要。
python 复制代码
import pandas as pd
import numpy as np

# 创建一个包含 NaN 值的 DataFrame
df = pd.DataFrame({
    'A': [1, 2, np.nan, 4],
    'B': [5, np.nan, 7, 8],
    # 'C': ['foo', 'bar', 'baz', 'qux']  # 非数值列
})

# 计算每列的中位数
median_per_column = df.median()
print("Median per column:")
print(median_per_column)

# 计算每行的中位数
median_per_row = df.median(axis='columns')
print("\nMedian per row:")
print(median_per_row)

# 只计算数值列的中位数
median_numeric_only = df.median(numeric_only=True)
print("\nMedian numeric only:")
print(median_numeric_only)

运行结果:

复制代码
Median per column:
A    2.0
B    7.0
dtype: float64

Median per row:
0    3.0
1    2.0
2    7.0
3    6.0
dtype: float64

Median numeric only:
A    2.0
B    7.0
dtype: float64

(5)min

用于计算 DataFrame 中数值的最小值

DataFrame.min(axis=0, skipna=True, numeric_only=False, **kwargs)

  • axis: {0 或 'index', 1 或 'columns'},默认为 0。这个参数决定了计算最小值是在哪个轴上进行:
    • 如果 axis=0 或 axis='index',则对每列进行计算,返回一个 Series,其索引为列名,值为每列的最小值。
    • 如果 axis=1 或 axis='columns',则对每行进行计算,返回一个 Series,其索引为行索引,值为每行的最小值。
  • skipna: 布尔值,默认为 True。如果为 True,则在计算最小值时会忽略 NaN 值。
  • numeric_only: 布尔值,默认为 False。如果为 True,则只对数值列进行计算,忽略非数值列。
  • **kwargs: 其他关键字参数。这些参数通常用于兼容性或特殊用途,通常不需要。
python 复制代码
import pandas as pd
import numpy as np

# 创建一个包含 NaN 值的 DataFrame
df = pd.DataFrame({
    'A': [1, 2, np.nan, 4],
    'B': [5, np.nan, 7, 8],
    'C': [6, 9, 3, 2],
    # 'C': ['foo', 'bar', 'baz', 'qux']  # 非数值列
})

# 计算每列的最小值
min_per_column = df.min()
print("Min per column:")
print(min_per_column)

# 计算每行的最小值
min_per_row = df.min(axis='columns')
print("\nMin per row:")
print(min_per_row)

# 只计算数值列的最小值
min_numeric_only = df.min(numeric_only=True)
print("\nMin numeric only:")
print(min_numeric_only)

运行结果:

复制代码
Min per column:
A    1.0
B    5.0
C    2.0
dtype: float64

Min per row:
0    1.0
1    2.0
2    3.0
3    2.0
dtype: float64

Min numeric only:
A    1.0
B    5.0
C    2.0
dtype: float64

(6)max

用于计算 DataFrame 中数值的最大值

DataFrame.max(axis=0, skipna=True, numeric_only=False, **kwargs)

  • axis: {0 或 'index', 1 或 'columns'},默认为 0。这个参数决定了计算最大值是在哪个轴上进行:
    • 如果 axis=0 或 axis='index',则对每列进行计算,返回一个 Series,其索引为列名,值为每列的最大值。
    • 如果 axis=1 或 axis='columns',则对每行进行计算,返回一个 Series,其索引为行索引,值为每行的最大值。
  • skipna: 布尔值,默认为 True。如果为 True,则在计算最大值时会忽略 NaN 值。
  • numeric_only: 布尔值,默认为 False。如果为 True,则只对数值列进行计算,忽略非数值列。
  • **kwargs: 其他关键字参数。这些参数通常用于兼容性或特殊用途,通常不需要。
python 复制代码
import pandas as pd
import numpy as np

# 创建一个包含 NaN 值的 DataFrame
df = pd.DataFrame({
    'A': [1, 2, np.nan, 4],
    'B': [5, np.nan, 7, 8],
    'C': [6, 9, 3, 2],
    # 'C': ['foo', 'bar', 'baz', 'qux']  # 非数值列
})

# 计算每列的最大值
max_per_column = df.max()
print("Max per column:")
print(max_per_column)

# 计算每行的最大值
max_per_row = df.max(axis='columns')
print("\nMax per row:")
print(max_per_row)

# 只计算数值列的最大值
max_numeric_only = df.max(numeric_only=True)
print("\nMax numeric only:")
print(max_numeric_only)

运行结果:

复制代码
Max per column:
A    4.0
B    8.0
C    9.0
dtype: float64

Max per row:
0    6.0
1    9.0
2    7.0
3    8.0
dtype: float64

Max numeric only:
A    4.0
B    8.0
C    9.0
dtype: float64

(7)var

用于计算 DataFrame 中数值的方差

DataFrame.var(axis=0, skipna=True, ddof=1, numeric_only=False, **kwargs)

  • axis: {0 或 'index', 1 或 'columns', None},默认为 0。这个参数决定了计算方差是在哪个轴上进行:
    • 如果 axis=0 或 axis='index',则对每列进行计算,返回一个 Series,其索引为列名,值为每列的方差。
    • 如果 axis=1 或 axis='columns',则对每行进行计算,返回一个 Series,其索引为行索引,值为每行的方差。
  • skipna: 布尔值,默认为 True。如果为 True,则在计算方差时会忽略 NaN 值。
  • ddof: 整数,默认为 1。Delta Degrees of Freedom,计算样本方差时使用的无偏估计的自由度修正。对于整个群体的方差,ddof 应该设置为 0。
  • numeric_only: 布尔值,默认为 False。如果为 True,则只对数值列进行计算,忽略非数值列。
  • **kwargs: 其他关键字参数。这些参数通常用于兼容性或特殊用途,通常不需要。
python 复制代码
import pandas as pd
import numpy as np

# 创建一个包含 NaN 值的 DataFrame
df = pd.DataFrame({
    'A': [1, 2, np.nan, 4],
    'B': [5, np.nan, 7, 8],
    'C': [6, 9, 3, 2],
    # 'C': ['foo', 'bar', 'baz', 'qux']  # 非数值列
})

# 计算每列的方差
var_per_column = df.var()
print("Variance per column:")
print(var_per_column)

# 计算每行的方差
var_per_row = df.var(axis='columns')
print("\nVariance per row:")
print(var_per_row)

# 只计算数值列的方差,并且使用无偏估计(ddof=1)
var_numeric_only = df.var(numeric_only=True, ddof=1)
print("\nVariance numeric only with ddof=1:")
print(var_numeric_only)

运行结果:

复制代码
Variance per column:
A     2.333333
B     2.333333
C    10.000000
dtype: float64

Variance per row:
0     7.000000
1    24.500000
2     8.000000
3     9.333333
dtype: float64

Variance numeric only with ddof=1:
A     2.333333
B     2.333333
C    10.000000
dtype: float64

(8)std

用于计算 DataFrame 中数值的标准差

DataFrame.std(axis=0, skipna=True, ddof=1, numeric_only=False, **kwargs)

  • axis: {0 或 'index', 1 或 'columns', None},默认为 0。这个参数决定了计算标准差是在哪个轴上进行:
    • 如果 axis=0 或 axis='index',则对每列进行计算,返回一个 Series,其索引为列名,值为每列的标准差。
    • 如果 axis=1 或 axis='columns',则对每行进行计算,返回一个 Series,其索引为行索引,值为每行的标准差。
  • skipna: 布尔值,默认为 True。如果为 True,则在计算标准差时会忽略 NaN 值。
  • ddof: 整数,默认为 1。Delta Degrees of Freedom,计算样本标准差时使用的无偏估计的自由度修正。对于整个群体的标准差,ddof 应该设置为 0。
  • numeric_only: 布尔值,默认为 False。如果为 True,则只对数值列进行计算,忽略非数值列。
  • **kwargs: 其他关键字参数。这些参数通常用于兼容性或特殊用途,通常不需要。
python 复制代码
import pandas as pd
import numpy as np

# 创建一个包含 NaN 值的 DataFrame
df = pd.DataFrame({
    'A': [1, 2, np.nan, 4],
    'B': [5, np.nan, 7, 8],
    'C': [6, 9, 3, 2],
    # 'C': ['foo', 'bar', 'baz', 'qux']  # 非数值列
})

# 计算每列的标准差
std_per_column = df.std()
print("Standard deviation per column:")
print(std_per_column)

# 计算每行的标准差
std_per_row = df.std(axis='columns')
print("\nStandard deviation per row:")
print(std_per_row)

# 只计算数值列的标准差,并且使用无偏估计(ddof=1)
std_numeric_only = df.std(numeric_only=True, ddof=1)
print("\nStandard deviation numeric only with ddof=1:")
print(std_numeric_only)

运行结果:

复制代码
Standard deviation per column:
A    1.527525
B    1.527525
C    3.162278
dtype: float64

Standard deviation per row:
0    2.645751
1    4.949747
2    2.828427
3    3.055050
dtype: float64

Standard deviation numeric only with ddof=1:
A    1.527525
B    1.527525
C    3.162278
dtype: float64

(9)quantile

用于计算 DataFrame 中数值的分位数

DataFrame.quantile(q=0.5, axis=0, numeric_only=False, interpolation='linear', method='single')

  • q: 可以是单个浮点数或浮点数列表,默认为 0.5。要计算的的分位数,应该在 0 到 1 之间。例如,q=0.5 表示中位数。
  • axis: {0 或 'index', 1 或 'columns'},默认为 0。这个参数决定了计算分位数是在哪个轴上进行:
    • 如果 axis=0 或 axis='index',则对每列进行计算,返回一个 Series 或 DataFrame,其索引为列名,值为每列的分位数。
    • 如果 axis=1 或 axis='columns',则对每行进行计算,返回一个 Series 或 DataFrame,其索引为行索引,值为每行的分位数。
  • numeric_only: 布尔值,默认为 False。如果为 True,则只对数值列进行计算,忽略非数值列。
  • interpolation: {'linear', 'lower', 'higher', 'midpoint', 'nearest'},默认为 'linear'。这个参数决定了分位数在数据不包含精确分位数值时的插值方法:
    • 'linear': 线性插值。
    • 'lower': 选择小于分位数的最大值。
    • 'higher': 选择大于分位数的最小值。
    • 'midpoint': 选择两个相邻数据的中间值。
    • 'nearest': 选择最接近分位数的值。
  • method: {'single', 'table'},默认为 'single'。这个参数决定了计算分位数的方法:
    • 'single': 对每列或每行单独计算分位数。
    • 'table': 使用整个表的分位数。选择table时,插值方法只能是higher、lower、nearest之一。
python 复制代码
import pandas as pd

# 创建一个DataFrame
data = {
    'col1': [10, 20, 30, 40, 50],
    'col2': [15, 25, 35, 45, 55],
    'col3': [20, 30, 40, 50, 60]
}
df = pd.DataFrame(data)

# 按列方向计算0.5分位数(中位数)
col_median = df.quantile(0.5, axis=0)
print("按列方向的0.5分位数(中位数):\n", col_median)

# 按行方向计算0.5分位数(中位数)
row_median = df.quantile(0.5, axis=1)
print("按行方向的0.5分位数(中位数):\n", row_median)

运行结果:

复制代码
按列方向的0.5分位数(中位数):
 col1    30.0
col2    35.0
col3    40.0
Name: 0.5, dtype: float64

按行方向的0.5分位数(中位数):
 0    15.0
1    25.0
2    35.0
3    45.0
4    55.0
Name: 0.5, dtype: float64

(10)cummax

用于计算 DataFrame 中数值的累积最大值

DataFrame.cummax(axis=0, skipna=True, *args, **kwargs)

  • axis: {0 或 'index', 1 或 'columns', None},默认为 0。这个参数决定了计算累积最大值是在哪个轴上进行:
    • 如果 axis=0 或 axis='index',则对每列进行计算,返回一个 DataFrame,其索引保持不变,每一列的值是自上而下(从第一行到当前行)的最大值
    • 如果 axis=1 或 axis='columns',则对每行进行计算,返回一个 DataFrame,其列保持不变,每一行的值是自左向右(从第一列到当前列)的最大值
  • skipna: 布尔值,默认为 True。如果为 True,则在计算累积最大值时忽略 NaN 值;如果为 False,则包含 NaN 值,可能导致结果中包含 NaN
  • *args 和 **kwargs: 这些参数用于传递给底层方法的其他参数,通常不需要使用
python 复制代码
import pandas as pd
import numpy as np

# 创建一个 DataFrame
df = pd.DataFrame({
    'A': [1, 2, np.nan, 4, 5],
    'B': [5, np.nan, 3, 2, 1],
})

# 计算每列的累积最大值
cummax_per_column = df.cummax(axis=0)
print("Cumulative max per column:")
print(cummax_per_column)

# 计算每行的累积最大值
cummax_per_row = df.cummax(axis=1)
print("\nCumulative max per row:")
print(cummax_per_row)

运行结果:

复制代码
Cumulative max per column:
     A    B
0  1.0  5.0
1  2.0  NaN
2  NaN  5.0
3  4.0  5.0
4  5.0  5.0

Cumulative max per row:
     A    B
0  1.0  5.0
1  2.0  NaN
2  NaN  3.0
3  4.0  4.0
4  5.0  5.0

(11)cummin

用于计算 DataFrame 中数值的累积最小值

DataFrame.cummin(axis=0, skipna=True, *args, **kwargs)

  • axis: {0 或 'index', 1 或 'columns', None},默认为 0。这个参数决定了计算累积最小值是在哪个轴上进行:
    • 如果 axis=0 或 axis='index',则对每列进行计算,返回一个 DataFrame,其索引保持不变,每一列的值是自上而下(从第一行到当前行)的最小值
    • 如果 axis=1 或 axis='columns',则对每行进行计算,返回一个 DataFrame,其列保持不变,每一行的值是自左向右(从第一列到当前列)的最小值
  • skipna: 布尔值,默认为 True。如果为 True,则在计算累积最小值时忽略 NaN 值;如果为 False,则包含 NaN 值,可能导致结果中包含 NaN
  • *args 和 **kwargs: 这些参数用于传递给底层方法的其他参数,通常不需要使用
python 复制代码
import pandas as pd
import numpy as np

# 创建一个 DataFrame
df = pd.DataFrame({
    'A': [3, 2, np.nan, 4, 1],
    'B': [5, np.nan, 3, 2, 6],
    'C': [6, 9, 3, 2, 5],
    # 'C': ['foo', 'bar', 'baz', 'qux', 'quux']  # 非数值列
})

# 计算每列的累积最小值
cummin_per_column = df.cummin(axis=0)
print("Cumulative min per column:")
print(cummin_per_column)

# 计算每行的累积最小值
cummin_per_row = df.cummin(axis=1)
print("\nCumulative min per row:")
print(cummin_per_row)

运行结果:

复制代码
Cumulative min per column:
     A    B  C
0  3.0  5.0  6
1  2.0  NaN  6
2  NaN  3.0  3
3  2.0  2.0  2
4  1.0  2.0  2

Cumulative min per row:
     A    B    C
0  3.0  3.0  3.0
1  2.0  NaN  2.0
2  NaN  3.0  3.0
3  4.0  2.0  2.0
4  1.0  1.0  1.0

(12)cumsum

用于计算 DataFrame 中数值的累积和。

DataFrame.cumsum(axis=0, skipna=True, *args, **kwargs)

  • axis : {0 或 'index', 1 或 'columns', None}, 默认为 0。这个参数决定了计算累积和是在哪个轴上进行:

    • 如果 axis=0 或 axis='index',则对每列进行计算,返回一个 DataFrame,其索引保持不变,每一列的值是自上而下(从第一行到当前行)的累积和。

    • 如果 axis=1 或 axis='columns',则对每行进行计算,返回一个 DataFrame,其列保持不变,每一行的值是自左向右(从第一列到当前列)的累积和。

  • skipna : 布尔值,默认为 True。如果为 True,则在计算累积和时忽略 NaN 值;如果为 False,则包含 NaN 值,可能导致结果中包含 NaN。

  • *args 和 **kwargs : 这些参数用于传递给底层方法的其他参数,通常不需要使用。

python 复制代码
import pandas as pd
import numpy as np

# 创建一个 DataFrame
df = pd.DataFrame({
    'A': [3, 2, np.nan, 4, 1],
    'B': [5, np.nan, 3, 2, 6],
    'C': [6, 9, 3, 2, 5],
    # 'C': ['foo', 'bar', 'baz', 'qux', 'quux']  # 非数值列
})

# 计算每列的累积和
cumsum_per_column = df.cumsum(axis=0)
print("Cumulative sum per column:")
print(cumsum_per_column)

# 计算每行的累积和
cumsum_per_row = df.cumsum(axis=1)
print("\nCumulative sum per row:")
print(cumsum_per_row)

运行结果:

复制代码
Cumulative sum per column:
      A     B   C
0   3.0   5.0   6
1   5.0   NaN  15
2   NaN   8.0  18
3   9.0  10.0  20
4  10.0  16.0  25

Cumulative sum per row:
     A    B     C
0  3.0  8.0  14.0
1  2.0  NaN  11.0
2  NaN  3.0   6.0
3  4.0  6.0   8.0
4  1.0  7.0  12.0

(13)cumprod

用于计算 DataFrame 中数值的累积乘积。

DataFrame.cumprod(axis=0, skipna=True, *args, **kwargs)

  • axis : {0 或 'index', 1 或 'columns', None}, 默认为 0。这个参数决定了计算累积乘积是在哪个轴上进行:

    • 如果 axis=0 或 axis='index',则对每列进行计算,返回一个 DataFrame,其索引保持不变,每一列的值是自上而下(从第一行到当前行)的累积乘积。

    • 如果 axis=1 或 axis='columns',则对每行进行计算,返回一个 DataFrame,其列保持不变,每一行的值是自左向右(从第一列到当前列)的累积乘积。

  • skipna : 布尔值,默认为 True。如果为 True,则在计算累积乘积时忽略 NaN 值;如果为 False,则包含 NaN 值,可能导致结果中包含 NaN。

  • *args 和 **kwargs : 这些参数用于传递给底层方法的其他参数,通常不需要使用。

python 复制代码
import pandas as pd
import numpy as np

# 创建一个 DataFrame
df = pd.DataFrame({
    'A': [3, 2, np.nan, 4, 1],
    'B': [5, np.nan, 3, 2, 6],
    'C': [6, 9, 3, 2, 5],
    # 'C': ['foo', 'bar', 'baz', 'qux', 'quux']  # 非数值列
})

# 计算每列的累积乘积
cumprod_per_column = df.cumprod(axis=0)
print("Cumulative product per column:")
print(cumprod_per_column)

# 计算每行的累积乘积
cumprod_per_row = df.cumprod(axis=1)
print("\nCumulative product per row:")
print(cumprod_per_row)

运行结果:

复制代码
Cumulative product per column:
      A      B     C
0   3.0    5.0     6
1   6.0    NaN    54
2   NaN   15.0   162
3  24.0   30.0   324
4  24.0  180.0  1620

Cumulative product per row:
     A     B     C
0  3.0  15.0  90.0
1  2.0   NaN  18.0
2  NaN   3.0   9.0
3  4.0   8.0  16.0
4  1.0   6.0  30.0

6. 分组与聚合

(1)groupby

用于将 DataFrame 分割成多个组,以便可以对这些组应用聚合函数或执行其他操作。

DataFrame.groupby(by=None, axis=0, level=None, as_index=True, sort=True, group_keys=True, observed=False, dropna=True)

  • by : 用于确定分组依据。

  • axis : {0 或 'index', 1 或 'columns'},默认为 0。这个参数决定了分组是在哪个轴上进行。

  • level : 如果轴是多索引,则按指定的索引级别分组。

  • as_index : 布尔值,默认为 True。当为 True 时,分组名称将作为结果的索引;如果为 False,则结果会保持原有的 DataFrame 结构,分组名称会作为一个普通列出现。

  • sort : 布尔值,默认为 True。如果为 True,则对分组键进行排序;如果为 False,则不排序,保持原有的分组顺序。

  • group_keys : 布尔值,默认为 True。如果为 True,则将组键添加到聚合后的结果中;如果为False,则不添加。

  • observed : 布尔值,默认为 False。仅当分组依据是多索引且包含分类数据时适用,如果为True,则仅显示分类数据中的观察值。

  • dropna : 布尔值,默认为 True。如果为 True,并且 by 是一个列表,则排除任何含有 NaN 的组。

一级索引:

python 复制代码
import pandas as pd

# 创建一个 DataFrame
df = pd.DataFrame({
    'A': ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'],
    'B': ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'],
    'C': [1, 3, 2, 5, 4, 1, 2, 3],
    'D': [2, 5, 3, 7, 6, 2, 4, 6]
})

# 按 'A' 和 'B' 列分组,并计算每组的平均值
grouped = df.groupby(['A', 'B']).mean()

print(grouped)

运行结果:

复制代码
             C    D
A   B              
bar one    3.0  5.0
    three  5.0  7.0
    two    1.0  2.0
foo one    1.5  3.0
    three  3.0  6.0
    two    3.0  4.5

多级索引:

python 复制代码
import pandas as pd

# 创建两个列表,它们将用作多级索引的级别
arrays = [['Falcon', 'Falcon', 'Parrot', 'Parrot'], # 第一级索引的值
          ['Captive', 'Wild', 'Captive', 'Wild']]  # 第二级索引的值

# 使用arrays列表创建一个DataFrame,'Max Speed'列包含对应于多级索引的数据
df = pd.DataFrame({'Max Speed': [390., 350., 30., 20.]}, # 数据
                  index=arrays) # 使用arrays列表作为多级索引

# 打印原始DataFrame,以查看其结构和数据
print(df)

# 使用groupby方法按第一级索引(即'arrays'列表的第一个元素)分组
# level=0表示按照多级索引的第一级进行分组
res = df.groupby(level=0).mean() # 计算每个组(即每个不同的第一级索引值)的平均速度

# 打印分组后的平均值,显示每个动物的Max Speed的平均值
print(res)

运行结果:

复制代码
                Max Speed
Falcon Captive      390.0
       Wild         350.0
Parrot Captive       30.0
       Wild          20.0
        Max Speed
Falcon      370.0
Parrot       25.0

(2)transform

对 DataFrame 或其中一个列应用一个函数,并返回一个与原始 DataFrame 具有相同索引的对象。此方法不会更改原始 DataFrame,而是返回一个新的 DataFrame,其中包含应用函数后的结果。

DataFrame.transform(func, axis=0, *args, **kwargs)

  • func : 函数,应用于每个组或列。这个函数可以是一个内置函数,比如 numpy.mean,也可以是一个自定义函数。

  • axis : {0 或 'index', 1 或 'columns'},默认为 0。这个参数决定了函数是在哪个轴上应用:

    • 如果 axis=0 或 axis='index',则函数按列应用。

    • 如果 axis=1 或 axis='columns',则函数按行应用。

  • *args : 位置参数,将传递给 func。

  • **kwargs : 关键字参数,将传递给 func。

python 复制代码
import pandas as pd

# 创建一个 DataFrame
df = pd.DataFrame({
    'A': [1, 2, 3, 4, 5],
    'B': [10, 20, 30, 40, 50],
    'C': [100, 200, 300, 400, 500]
})

def square(x):
    return x ** 2

# 调用transform函数,并将自定义函数带入
transformed_df = df.transform(square)

print(transformed_df)

运行结果:

复制代码
    A     B       C
0   1   100   10000
1   4   400   40000
2   9   900   90000
3  16  1600  160000
4  25  2500  250000

(3)agg

它允许你应用一个或多个聚合函数到 DataFrame 的列或行上,并返回聚合后的结果。

DataFrame.agg(func=None, axis=0, *args, **kwargs)

  • func : 函数或函数列表/字典,应用于 DataFrame 的列或行。如果传递一个函数,它将应用于所有列。如果传递一个函数列表或字典,则可以分别对不同的列应用不同的函数。可以使用的函数包括NumPy 的统计函数、Python 的内置函数、Pandas 的自定义聚合函数,或者自定义的 lambda 函数。

  • axis : {0 或 'index', 1 或 'columns'},默认为 0。这个参数决定了聚合操作是在哪个轴上执行:

    • 如果 axis=0 或 axis='index',则函数按列应用(逐行操作)。

    • 如果 axis=1 或 axis='columns',则函数按行应用(逐列操作)。

  • *args : 位置参数,将传递给 func。

  • **kwargs : 关键字参数,将传递给 func。

python 复制代码
import pandas as pd

# 创建一个 DataFrame
df = pd.DataFrame({
    'A': [1, 2, 3, 4, 5],
    'B': [10, 20, 30, 40, 50]
})

# 应用单个聚合函数,计算每列的平均值
print("每列的平均值:")
result = df.agg('mean')
print(result)

# 对列 'A' 应用 'sum' 函数,对列 'B' 应用 'mean' 函数
print("\nA-sum,B-mean:")
result = df.agg({'A': 'sum', 'B': 'mean'})
print(result)

# 对所有列应用多个聚合函数
print("\n多个聚合函数:")
result = df.agg(['min', 'max', 'sum'])
print(result)

# 定义一个自定义函数

def custom_agg(x):
    return (x.max() - x.min()) / x.std()

# 使用自定义函数进行聚合
print("\n自定义函数:")
result = df.agg(custom_agg)
print(result)

运行结果:

复制代码
每列的平均值:
A     3.0
B    30.0
dtype: float64

A-sum,B-mean:
A    15.0
B    30.0
dtype: float64

多个聚合函数:
      A    B
min   1   10
max   5   50
sum  15  150

自定义函数:
A    2.529822
B    2.529822
dtype: float64

7. 数据可视化

(1)plot

用于绘制 DataFrame 数据图形,它允许用户直接从 DataFrame 创建各种类型的图表 ,而不需要使用其他绘图库(底层实际上使用了 Matplotlib)。

DataFrame.plot(*args, **kwargs)

以下是一些常见的 DataFrame.plot 方法的关键字参数:

  • kind : {'line', 'bar', 'barh', 'hist', 'box', 'kde', 'density', 'area', 'pie', 'scatter', 'hexbin'},默认为'line'。这个参数决定了要绘制哪种类型的图表。

  • ax : Matplotlib axes 对象,可选。如果提供,则绘图将在指定的 axes 对象上进行。

  • subplots : 布尔值,默认为 False。如果为 True,则每个数值列将绘制在其自己的子图中。

  • sharex : 布尔值,默认为 False。如果为 True,并且 subplots 为 True,则所有子图共享相同的x 轴。

  • sharey : 布尔值,默认为 False。如果为 True,并且 subplots 为 True,则所有子图共享相同的y 轴。

  • layout : 元组(行数,列数),可选。用于安排子图的布局。

  • figsize : 元组(宽度,高度),可选。用于设置图表的大小。

  • use_index : 布尔值,默认为 True。如果为 True,则将 DataFrame 的索引用作 x 轴。

  • title : 字符串,可选。图表的标题。

  • grid : 布尔值,默认为 None。如果为 True,则在图表上显示网格线。

python 复制代码
import pandas as pd
import matplotlib.pyplot as plt

# 创建一个 DataFrame
df = pd.DataFrame({
    'A': [1, 2, 3, 4, 5],
    'B': [10, 20, 30, 40, 50]
})

# 绘制线图
df.plot(kind='line')

# 显示图像
plt.show()

(2)hist

用于绘制 DataFrame 中数据的直方图

DataFrame.hist(column=None, by=None, grid=True, xlabelsize=None, xrot=None, ylabelsize=None, yrot=None, ax=None, sharex=False, sharey=False, figsize=None, layout=None, bins=10, backend=None, legend=False, **kwargs)

  • column : 字符串或字符串列表,可选。用于指定要绘制直方图的列。如果未指定,则默认绘制所有数值列的直方图。

  • by : 字符串或字符串列表,可选。用于指定分组变量,以便为每个组绘制直方图。

  • grid : 布尔值,默认为 True。是否在直方图上显示网格线。

  • xlabelsize : 整数,可选。用于设置 x 轴标签的大小。

  • xrot : 浮点数,可选。用于设置 x 轴标签的旋转角度。

  • ylabelsize : 整数,可选。用于设置 y 轴标签的大小。

  • yrot : 浮点数,可选。用于设置 y 轴标签的旋转角度。

  • ax : Matplotlib axes 对象或数组,可选。如果提供,则在指定的 axes 对象上绘制直方图。

  • sharex : 布尔值,默认为 False。如果为 True,并且绘制多个直方图,则所有直方图共享相同的 x轴。

  • sharey : 布尔值,默认为 False。如果为 True,并且绘制多个直方图,则所有直方图共享相同的 y轴。

  • figsize : 元组(宽度,高度),可选。用于设置整个图形的大小。

  • layout : 元组(行数,列数),可选。用于指定直方图的布局。

  • bins : 整数或序列,默认为 10。用于设置直方图的柱子数量或边界。

  • backend : 字符串,可选。用于指定绘图的后端。默认情况下,Pandas 使用 Matplotlib。

  • legend : 布尔值,默认为 False。如果为 True,并且指定了 by 参数,则在直方图上显示图例。

  • **kwargs : 关键字参数,这些参数会被传递给 Matplotlib 的 hist 函数,用于进一步自定义直方图。

python 复制代码
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

# 创建一个包含正态分布数据的 DataFrame
df = pd.DataFrame(np.random.randn(100, 3), columns=['A', 'B', 'C'])

# 绘制 A 列的直方图,设置 20 个柱子,并指定图形大小
df['A'].hist(bins=20, figsize=(8, 4))

# 绘制所有列的直方图,每个直方图在不同的子图中
df.hist(figsize=(10, 7), bins=30)

# 使用 by 参数按列 B 的值分组绘制列 A 的直方图
df.hist(column='A', by='B', bins=15, figsize=(10, 5))

# 使用 tight_layout 自动调整子图布局
fig.tight_layout()

# 显示图像
plt.show()

8. 其他常用方法

(1)nunique

用于计算 DataFrame 中唯一值的数量

DataFrame.nunique(axis=0, dropna=True)

  • axis=0:默认值,表示按列进行操作。如果设置为 axis=1,则表示按行进行操作。

  • dropna=True:默认值,表示在计算唯一值之前先排除掉缺失值(NaN)。如果设置为 False,则缺失值也会被计算在内。

python 复制代码
import pandas as pd
import numpy as np

# 创建一个DataFrame
df = pd.DataFrame({
    'A': [1, 2, 2, 3, 3, 3],
    'B': ['a', 'b', 'b', 'c', 'c', 'c'],
    'C': [np.nan, np.nan, 1, 2, 2, 2]
})

# 使用nunique()方法计算每列的唯一值数量
unique_counts = df.nunique(axis=0, dropna=True)

print(unique_counts)

(2)value_counts

用于计算 DataFrame 中各个值出现的频率的一个方法

DataFrame.value_counts(subset=None, normalize=False, sort=True, ascending=False, dropna=True)

  • subset=None:可选参数,用于指定要进行计算操作的列名列表。如果未指定,则对整个DataFrame的所有列进行操作

  • normalize=False:布尔值,默认为False。如果设置为True,则返回每个值的相对频率,而不是计数

  • sort=True:布尔值,默认为True。如果设置为True,则结果将按计数值降序排序

  • ascending=False:布尔值,默认为False。当 sort=True 时,此参数指定排序顺序。如果设置为True,则结果将按计数值升序排序

  • dropna=True:布尔值,默认为True。如果设置为True,则在计数之前排除缺失值

python 复制代码
import pandas as pd
import numpy as np

# 创建一个DataFrame
df = pd.DataFrame({
    'A': [1, 2, 2, 3, 3, 3],
    'B': ['a', 'b', 'b', 'c', 'c', 'c'],
    'C': [np.nan, np.nan, 1, 2, 2, 2]
})

# 使用value_counts()方法计算值的频率
# 计算 A、B 列,计数,排序,降序,计数前排除空值
value_counts = df.value_counts(subset=['A', 'B'], normalize=False, sort=True, ascending=False, dropna=True)

print(value_counts)

(3)describe

用于生成 DataFrame 中数值列的统计摘要,会返回一个 DataFrame,其中包含以下统计信息:

  • count:非NA值的数量

  • mean:平均值

  • std:标准差

  • min:最小值

  • 分位数:可指定

  • max:最大值

DataFrame.describe(percentiles=None, include=None, exclude=None)

  • percentiles=None:一个列表形式的数值,用于指定要计算的分位数。默认情况下,会计算25%,50%,和75%这三个分位数。如果你想要不同的分位数,可以在这里指定。

  • include=None:一个列表形式的字符串或字符串序列,用于指定要包含在描述统计中的数据类型。默认情况下,只包括数值类型的数据。

  • exclude=None:一个列表形式的字符串或字符串序列,用于指定要从描述统计中排除的数据类型。

Pandas 3 中,字符串类型处理规则发生了变化,exclude=['object'] 以前会兼容性地排除 str 类型,但该行为现已弃用,因此触发警告;由于 include=['number'] 已限定只统计数值列,可以直接删除 exclude=['object']。

python 复制代码
import pandas as pd

# 创建一个DataFrame
df = pd.DataFrame({
    'A': [1, 2, 2, 3, 3, 3],
    'B': [10, 20, 20, 30, 30, 30],
    'C': ['foo', 'bar', 'bar', 'baz', 'baz', 'baz']
})

# 使用describe()方法生成统计摘要
# description = df.describe(percentiles=[0.5, 0.75, 0.9], include=['number'], exclude=['object'])
description = df.describe(percentiles=[0.5, 0.75, 0.9], include=['number'])

print(description)

(4)copy

用于创建DataFrame 的一个副本

DataFrame.copy(deep=True)

  • deep=True:默认为True,表示创建一个深拷贝。
    • 在深拷贝中,DataFrame 中的所有数据都会被复制到新的DataFrame 中,因此原始 DataFrame 中的数据与副本 DataFrame 中的数据是完全独立的
    • 如果你对副本进行修改,原始 DataFrame 不会受到影响,反之亦然

Pandas 3 中:

  • df.copy():创建深拷贝,修改副本不会影响原数据。
  • df.copy(deep=False):创建浅拷贝,在 Pandas 3 的写时复制机制下,修改副本也不会影响原数据。

Pandas 3 默认采用 Copy-on-Write(写时复制)机制,df['A'][0] = 999 这类链式赋值在旧版本中可能通过视图修改原数据,但在新版本中中间对象会被视为独立副本,无法可靠地更新原 DataFrame,因此应使用 df.loc[0, 'A'] = 999 一步完成赋值,避免 ChainedAssignmentError

python 复制代码
import pandas as pd

# 创建一个 DataFrame
df = pd.DataFrame({
    'A': [1, 2, 3],
    'B': [4, 5, 6]
})

# 创建深拷贝
df_deep_copy = df.copy()

# 创建浅拷贝
df_shallow_copy = df.copy(deep=False)

# 修改深拷贝中的数据
# df_deep_copy['A'][0] = 999
df_deep_copy.loc[0,'A'] = 999

# 修改浅拷贝中的数据
# df_shallow_copy['B'][0] = 888
df_shallow_copy.loc[0,'B'] = 888

# 打印原始DataFrame和副本
print("Original DataFrame:")
print(df)
print("\nDeep Copy:")
print(df_deep_copy)
print("\nShallow Copy:")
print(df_shallow_copy)

运行结果:

复制代码
Original DataFrame:
   A  B
0  1  4
1  2  5
2  3  6

Deep Copy:
     A  B
0  999  4
1    2  5
2    3  6

Shallow Copy:
   A    B
0  1  888
1  2    5
2  3    6

(5)reset_index

用于重置DataFrame 的索引

将原来的行索引恢复为默认的整数索引(从 0 开始),原索引可以选择保留为普通列或直接丢弃

DataFrame.reset_index(level=None, *, drop=False, inplace=False, col_level=0, col_fill='', allow_duplicates=_NoDefault.no_default, names=None)

  • level=None:整数或索引名称,用于指定要重置的索引级别。对于多级索引的DataFrame,可以指定一个级别或级别列表。如果为None,则重置所有级别。

  • drop=False:布尔值,默认为False。如果为True,则重置索引后,原始索引将不会作为列添加到DataFrame 中。如果为False,则原始索引将作为新列添加到DataFrame 中。

  • inplace=False:布尔值,默认为False。如果为True,则直接在原始DataFrame 上进行操作,不返回新的DataFrame。

  • col_level=0:如果原始索引是多级索引,则指定新列的索引级别。

  • col_fill='':如果原始索引是多级索引,并且 col_level 比原始索引的级别多,则使用此值填充缺失的级别。

  • allow_duplicates=_NoDefault.no_default:允许索引列中出现重复值。如果设置为False,则在尝试插入重复列时会引发ValueError。

  • names=None:列表或元组,用于为新列指定名称。默认情况下,如果 drop 为False,则使用原始索引的名称。

python 复制代码
import pandas as pd

# 创建两个列表,它们将用作多级索引的级别
arrays = [['Falcon', 'Falcon', 'Parrot', 'Parrot'], # 第一级索引的值
          ['Captive', 'Wild', 'Captive', 'Wild']]  # 第二级索引的值

# 使用 arrays 列表创建一个 DataFrame,'Max Speed' 列包含对应于多级索引的数据
df = pd.DataFrame({'Max Speed': [390., 350., 30., 20.]}, # 数据
                  index=arrays) # 使用arrays列表作为多级索引

print("原始的:")
print(df)

# 重置所有索引级别,并将它们作为列添加到 DataFrame 中
print("\n重置的:")
df_reset = df.reset_index()
print(df_reset)


# 只重置第二级索引,并将它作为列添加到 DataFrame中
print("\n只重置第二级索引")
df_reset_level_1 = df.reset_index(level=1)
print(df_reset_level_1)

# 重置所有索引级别,但不将它们作为列添加到 DataFrame中
print("\n重置所有索引,但是不保存:")
df_reset_drop = df.reset_index(drop=True)
print(df_reset_drop)

运行结果:

复制代码
原始的:
                Max Speed
Falcon Captive      390.0
       Wild         350.0
Parrot Captive       30.0
       Wild          20.0

重置的:
  level_0  level_1  Max Speed
0  Falcon  Captive      390.0
1  Falcon     Wild      350.0
2  Parrot  Captive       30.0
3  Parrot     Wild       20.0

只重置第二级索引
        level_1  Max Speed
Falcon  Captive      390.0
Falcon     Wild      350.0
Parrot  Captive       30.0
Parrot     Wild       20.0

重置所有索引,但是不保存:
   Max Speed
0      390.0
1      350.0
2       30.0
3       20.0

(6)info

用于显示DataFrame 的概要信息的一个便捷方法,它提供了关于 DataFrame 的列、非空值数量、数据类型以及内存使用情况的信息。

DataFrame.info(verbose=None, buf=None, max_cols=None, memory_usage=None, show_counts=None)

  • verbose=None:控制输出信息的详细程度。

  • buf=None:一个打开的文件对象或类似文件的对象。如果提供,则输出将被写入这个缓冲区而不是标准输出。

  • max_cols=None:要显示的最大列数。如果DataFrame 的列数超过这个值,则只会显示部分列的信息。

  • memory_usage=None:控制是否显示内存使用情况。可以设置为True或False,或者是一个字符串,'deep'表示深度计算内存使用情况,考虑对象内部数据。

  • show_counts=None:控制是否显示非空值的数量。如果设置为True,则会在每个列旁边显示非空值的数量。

    import pandas as pd

    创建一个DataFrame

    df = pd.DataFrame({
    'A': [1, 2, 3, None],
    'B': ['a', 'b', 'c', 'd'],
    'C': [1.1, 2.2, 3.3, 4.4]
    })

    显示DataFrame的概要信息

    df.info(verbose=True, memory_usage='deep', show_counts=True)

运行结果:

复制代码
<class 'pandas.DataFrame'>
RangeIndex: 4 entries, 0 to 3
Data columns (total 3 columns):
 #   Column  Non-Null Count  Dtype  
---  ------  --------------  -----  
 0   A       3 non-null      float64
 1   B       4 non-null      str    
 2   C       4 non-null      float64
dtypes: float64(2), str(1)
memory usage: 396.0 bytes

(7)apply

允许你对DataFrame 中的每个元素、行或列应用一个函数。

DataFrame.apply(func, axis=0, raw=False, result_type=None, args=(), **kwargs)

  • func:函数,应用于每个元素、行或列。这个函数需要你自定义,或者使用内置的函数。

  • axis=0:指定应用函数的轴。

  • raw=False:布尔值,默认为False,则每行或每列将作为Series使用,如果为True,则将作为Ndarray数组,性能会更好。

  • result_type=None:控制返回类型。可以是以下之一:

    • 'reduce':如果可能的话,如果应用函数返回一个列表,这个列表会被转换成一个 Series。

    • 'broadcast':结果会被广播到原始 DataFrame 的形状,保留原始的索引和列。

    • 'expand':如果应用函数返回一个列表(或类似列表的结构),则这个列表会被转换为多个列。这意味着每个列表元素都会变成 DataFrame 的一列。

  • args=():元组,包含传递给函数的位置参数。

  • **kwargs:关键字参数,将被传递给函数。

python 复制代码
import pandas as pd

# 创建一个DataFrame
df = pd.DataFrame({
    'A': [1, 2, 3],
    'B': [4, 5, 6],
    'C': [7, 8, 9]
})
print(df)

# 定义一个函数,计算每行的平均值
def mean_row(row):
    return row.mean()

# 应用函数到每行
result = df.apply(mean_row, axis=1)

print(result)

运行结果:

复制代码
   A  B  C
0  1  4  7
1  2  5  8
2  3  6  9

0    4.0
1    5.0
2    6.0
dtype: float64

(四)保存与读取

1. to_csv

用于将DataFrame 对象保存为CSV(逗号分隔值)文件的方法

DataFrame.to_csv(path_or_buf=None, sep=',', na_rep='', float_format=None, columns=None, header=True, index=True, mode='w', encoding=None, quoting=None, quotechar='"', **kwargs)

  • path_or_buf : 指定输出文件的路径或文件对象。

  • sep : 字段分隔符,通常使用逗号 , 或制表符 \t。

  • na_rep : 缺失值的表示方式,默认为空字符串 ''。

  • float_format : 浮点数的格式化方式,例如 '%.2f' 用于格式化为两位小数。

  • columns : 要写入的列的子集,默认为None,表示写入所有列。

  • header : 是否写入列名,通常设置为True。

  • index : 是否写入行索引,通常设置为True或False,取决于是否需要索引。

  • mode : 写入模式,通常使用'w'(写入,覆盖原文件)或'a'(追加到文件末尾)。

  • encoding : 文件编码,特别是在处理非ASCII 字符时很重要

  • quoting : 控制字段引用的行为,通常用于确保字段中的分隔符被正确处理。

  • quotechar : 用于包围字段的字符,默认为双引号 "。

  • **kwargs : 其他关键字参数。

python 复制代码
import pandas as pd

# 创建一个简单的DataFrame
data = {
    '姓名' : ['张三' , '李四' , '王五' ],
    '年龄' : [28, 34, 29],
    '城市' : ['北京' , '上海' , '广州' ]
}

df = pd.DataFrame(data)
# 将DataFrame保存为CSV文件
df.to_csv('人员信息.csv' , index=False, encoding='utf_8_sig')

2. to_excel

在操作excel表格之前,需要安装一个库: openpyxl,因为 pandas 库本身并不包含写入Excel文件的直接支持,如果没有安装的话将无法操作excel。

pip install openpyxl

Pandas中的 to_excel 用于将 DataFrame 保存为 Excel文件。

DataFrame.to_excel(excel_writer, sheet_name='Sheet1', na_rep='', float_format=None, columns=None, header=True, index=True, index_label=None, startrow=0, startcol=0, engine=None, merge_cells=True, inf_rep='inf', freeze_panes=None, storage_options=None)

  • excel_writer:字符串或ExcelWriter对象,指定输出文件的路径或文件对象。

  • sheet_name='Sheet1':要写入的工作表名称。

  • na_rep='':指定缺失值的表示方式。

  • float_format=None:浮点数的格式化方式,例如'%.2f'。

  • columns=None:要写入的列的子集,默认为None,表示写入所有列。

  • header=True:是否写入列名,默认为True。

  • index=True:是否写入行索引,默认为True。

  • index_label=None:指定行索引列的列名,如果为None,并且 header 为True,则使用索引名。

  • startrow=0:写入DataFrame 的起始行位置,默认为0。

  • startcol=0:写入DataFrame 的起始列位置,默认为0。

  • engine=None:指定用于写入文件的引擎,可以是'openpyxl' (默认)或'xlsxwriter'。

  • merge_cells=True:是否合并单元格,这在有合并单元格的Header时很有用。

  • inf_rep='inf':指定无限大的表示方式。

  • freeze_panes=None:指定冻结窗口的单元格范围,例如'A2'。

  • storage_options=None:指定存储连接的参数,例如认证凭据。

python 复制代码
import pandas as pd

# 创建一个简单的DataFrame
data = {
    '姓名' : ['张三' , '李四' , '王五' ],
    '年龄' : [28, 34, 29],
    '城市' : ['北京' , '上海' , '广州' ]
}

df = pd.DataFrame(data)
# 将DataFrame保存为Excel文件
df.to_excel('人员信息.xlsx' , index=False)

3. read_csv

pandas.read_csv 是一个非常强大的函数,用于从文件、URL、文件-like对象等读取逗号分隔值(CSV)文件。这个函数有很多参数,允许你以多种方式自定义数据加载过程。

pandas.read_csv(filepath_or_buffer, sep, header, usercols, na_values, parse_dates, skiprows, nrows)

  • filepath_or_buffer:指定要读取的 CSV 文件的路径或文件对象。可以是一个字符串,表示文件的绝对路径或相对路径;也可以是一个已经打开的文件对象(例如通过 open() 函数打开的文件)。

  • sep : 字符串,用于分隔字段的字符。默认是逗号 ,,但可以是任何字符,例如 ';' 或 '\t' (制表符)。

  • header : 整数或整数列表,用于指定行号作为列名,或者没有列名(例如 header=None)。默认为 'infer',表示自动检测列名。

  • usecols : 列表或 callable,用于指定要读取的列。可以是列名的列表,也可以是列号的列表。

  • na_values : 字符串、列表或字典,用于指定哪些其他值应该被视为 NA/NaN。

  • parse_dates : 列表或字典,用于指定将哪些列解析为日期。

  • skiprows : 整数或列表,用于指定要跳过的行号或条件。

  • nrows : 整数,用于指定要读取的行数。

python 复制代码
import pandas as pd

c = pd.read_csv("人员信息.csv")

print(c)

4. read_excel

pandas.read_excel 是pandas库中用于读取Excel文件( .xls 或 .xlsx)的函数。它可以将Excel文件中的数据读取为DataFrame 对象,便于进行数据分析和处理。

pandas.read_excel(io, sheet_name=0, header=0, index_col=None, usecols=None, squeeze=False, dtype=None, skiprows=None, nrows=None, na_values=None, keep_default_na=True, parse_dates=False, date_parser=None, skipfooter=0, convert_float=True, **kwds)

  • io : 文件路径或文件对象。这是唯一必需的参数,用于指定要读取的Excel文件。

  • sheet_name=0 : 要读取的表名或表的索引号。默认为0,表示读取第一个工作表。可以指定工作表名或索引号,如果指定多个,将返回一个字典,键为工作表名,值为对应的DataFrame。

  • header=0 : 用作列名的行号,默认为0,即第一行作为列名。如果没有标题行,可以设置为None。

  • index_col=None : 用作行索引的列号或列名。默认为None,表示不使用任何列作为索引。可以是一个整数、字符串或列名的列表。

  • usecols=None : 要读取的列。默认为None,表示读取所有列。可以是一个整数列表、字符串列表或Excel列的位置(如 [0, 1, 2])或字母标记(如 ['A', 'B', 'C'])。

  • squeeze=False : 如果读取的数据只有一列,当设置为True时,返回一个Series而不是DataFrame。

  • dtype=None : 指定某列的数据类型。默认为None,表示自动推断。可以是一个字典,键为列名,值为NumPy数据类型。

  • skiprows=None : 要跳过的行号或行号列表。默认为None,表示不跳过任何行。可以是整数或整数列表。

  • nrows=None : 读取的行数,从文件头开始。默认为None,表示读取所有行。

  • na_values=None : 将指定的值替换为NaN。默认为None,表示不替换。可以是一个值或值的列表。

  • keep_default_na=True : 如果为True(默认),则除了通过 na_values 指定的值外,还将默认的NaN值视为NaN。

  • parse_dates=False : 是否尝试将列解析为日期。默认为False。可以是一个布尔值、列名列表或列号的列表。

  • date_parser=None : 用于解析日期的函数。默认为None,表示使用pandas默认的日期解析器。

  • skipfooter=0 : 要跳过的文件底部的行数。默认为0,表示不跳过任何底部的行。

  • convert_float=True : 是否将所有浮点数转换为64位浮点数。默认为True,以避免数据类型推断问题。

  • **kwds : 允许用户传递其他关键字参数,这些参数可能会被引擎特定的读取器所识别。

python 复制代码
import pandas as pd

x = pd.read_excel("人员信息.xlsx")

print(x)
相关推荐
大雾的小屋1 小时前
卷积神经网络原理解析:从1989年手写邮编识别到现代计算机视觉
人工智能·计算机视觉·cnn
第九序言T1 小时前
Python 数据处理进阶(二十四)把脚本变成工具:argparse、logging 与定时任务
python·自动化·pandas
Luchang-Li1 小时前
DeepSeek v4.1 Flash SGLang引擎KV cache存储逻辑
人工智能
这是谁的博客?2 小时前
CUDA 内存一致性模型与同步原语深度解析:从弱内存序、作用域可见性到异步代理栅栏的 GPU 并发正确性底层原理
人工智能
shelly聊外贸2 小时前
WhatsApp 聊天记录如何导出为 CSV?使用 Python 进行数据分析
开发语言·python·数据分析
u1301302 小时前
GitHub 热榜项目:周榜(2026-11-01)
人工智能·github
I Am a robert girl2 小时前
从 FlowAct-R2 拆解“会说话的数字人“:流式多模态参考与主动式 Agent 规划
python·数字人·多模态大模型·扩散transformer·流式生成·agent规划
lifallen2 小时前
ub-mode skill:软件工程原则
人工智能·学习·ai·软件工程·ai编程
Geek-Chow2 小时前
05.4 · DeepInfer 推理框架总览:源码结构、开源与未开源部分对照
人工智能