pandas 模块介绍

pandas简介
pandas官网:https://pandas.pydata.org/pandas-docs/stable/reference/


Pandas主要特点和功能:
数据结构:Pandas 提供了两种主要的数据结构:Series 和 DataFrame。Series 是一维标记数组,类似于 Python 中的列表或 NumPy 中的数组,而 DataFrame 是一个二维的表格型数据结构,类似于 SQL 表或 Excel 表格。
数据加载与保存:Pandas 可以从各种数据源加载数据,包括 CSV 文件、Excel 表格、SQL 数据库、JSON 文件等,并且可以将处理后的数据保存到这些格式中。
数据清洗与转换:Pandas 提供了丰富的函数和方法,用于数据清洗、处理缺失值、重复值、异常值等,以及进行数据转换、重塑和合并操作。
数据分析与统计:Pandas 提供了各种统计函数和方法,用于描述性统计、聚合操作、分组运算、透视表等数据分析任务。
数据可视化:Pandas 结合了 Matplotlib 库,可以轻松地进行数据可视化,绘制各种统计图表,如折线图、散点图、直方图等。


pandas教程

点击查看代码
第一章、pandas数据结构之Series
Pandas 的主要数据结构是 Series (一维数据)与 DataFrame(二维数据)。

Series 是一种类似于一维数组的对象,它由一组数据(各种 Numpy 数据类型)以及一组与之相关的数据标签(即索引)组成。
Series(系列)是能够保存任何类型数据的一维数组,例如能保存整数、字符串、浮点数、Python对象等。

Series 特点:
一维数组:Series是一维的,这意味着它只有一个轴(或维度),类似于 Python 中的列表。
索引: 每个 Series 都有一个索引,它可以是整数、字符串、日期等类型。如果不指定索引,Pandas 将默认创建一个从 0 开始的整数索引。
数据类型: Series 可以容纳不同数据类型的元素,包括整数、浮点数、字符串、Python 对象等。
大小不变性:Series 的大小在创建后是不变的,但可以通过某些操作(如 append 或 delete)来改变。
操作:Series 支持各种操作,如数学运算、统计分析、字符串处理等。
缺失数据:Series 可以包含缺失数据,Pandas 使用NaN(Not a Number)来表示缺失或无值。

series 是一种类似于一维数组的对象,由下面两个部分组成:
values:一维数组(ndarray类型)
index:相关的数据索引标签

一、series的创建
创建series的语法;
pandas.Series(data=None, index=None, dtype=None, name=None, copy=False, fastpath=False)

参数说明:
data:Series 的数据部分,可以是列表、数组、字典、标量值等。如果不提供此参数,则创建一个空的 Series。
index:Series 的索引部分,用于对数据进行标记。可以是列表、数组、索引对象等。如果不提供此参数,则创建一个默认的整数索引。
dtype:指定 Series 的数据类型。可以是 NumPy 的数据类型,例如 np.int64、np.float64 等。如果不提供此参数,则根据数据自动推断数据类型。
name:Series 的名称,用于标识 Series 对象。如果提供了此参数,则创建的 Series 对象将具有指定的名称。
copy:是否复制数据。默认为 False,表示不复制数据。如果设置为 True,则复制输入的数据。
fastpath:是否启用快速路径。默认为 False。启用快速路径可能会在某些情况下提高性能。


series两种常用的创建方式:
1、由列表或numpy数组创建
# 列表方式
list1 = [11, 22, 33]
print(pd.Series(list1))

0    11
1    22
2    33
dtype: int64

# 数组方式
array = np.array(list1)
print(pd.Series(array))
0    11
1    22
2    33
dtype: int32

# index和values
list1 = [11, 22, 33]
series = pd.Series(list1)
print(series.index)    # RangeIndex(start=0, stop=3, step=1)
print(series.values)   # [11 22 33]

# 修改索引,注意,索引数量要和值的数量一样
list1 = [11, 22, 33]
series = pd.Series(list1)
series.index = ['A', 'B', 'C']
series.index = list('ABC')
print(series)

# 通过索引获取值
list1 = [11, 22, 33]
series = pd.Series(list1)
print(series[0])

# 通过索引修改值
list1 = [11, 22, 33]
series = pd.Series(list1)
series[0] = 111
print(series)



2、通过字典创建series
dict1 = {'a': "Google", 'b': "Runoob", 'c': "Wiki"}
series = pd.Series(dict1)
print(series)   # 字典的key做索引
a    Google
b    Runoob
c      Wiki
dtype: object


二、series的索引
可以使用中括号取单个索引值(此时返回的是元素类型)或者中括号里一个列表取多个索引值(此时返回的仍然是一个
series类型)。分为显示索引和隐式索引:
(1)显示索引就是使用索引名:
使用index中的元素作为索引值
dict1 = {'a': "Google", 'b': "Runoob", 'c': "Wiki"}
series = pd.Series(dict1)
print(series[['a', 'b']])  
a    Google
b    Runoob
dtype: object

使用.loc[](推荐)
dict1 = {'a': "Google", 'b': "Runoob", 'c': "Wiki"}
series = pd.Series(dict1)
print(series.loc[['a', 'b']])
a    Google
b    Runoob
dtype: object

(2)隐式索引就是使用下标:
使用整数作为索引值,注意,该种方式后续版本准备丢弃
dict1 = {'a': "Google", 'b': "Runoob", 'c': "Wiki"}
series = pd.Series(dict1)
print(series[[0, 1]])
a    Google
b    Runoob
dtype: object

使用iloc[](推荐)
dict1 = {'a': "Google", 'b': "Runoob", 'c': "Wiki"}
series = pd.Series(dict1)
print(series.iloc[[0, 1]])
a    Google
b    Runoob
dtype: object


三、series显示切片和隐式切片
显示切片就是用索引名,显示切片左闭右闭,可以用中括号也可以用.loc[]:
dict1 = {'a': "Google", 'b': "Runoob", 'c': "Wiki"}
series = pd.Series(dict1)
print(series['a':'c'])
a    Google
b    Runoob
c      Wiki
dtype: object

隐式切片就是用下标,隐式切片是左闭右开,可以用中括号也可以用.iloc[]:
dict1 = {'a': "Google", 'b': "Runoob", 'c': "Wiki"}
series = pd.Series(dict1)
print(series.iloc[0:2])
a    Google
b    Runoob
dtype: object

四、series基本属性和方法
Series有一些常用属性:
属性名	含义
size	表示值的个数。
index	表示列索引数,结果是 RangeIndex(start=0, stop=5, step=1),可以用list进行类型转换,转换后结果为[0, 1, 2, 3, 4]。
dtype	表示列的数据类型。
shape	表示形状,有多少列,是个数组。
values	表示对象值,是个一维数组,<class 'numpy.ndarray'>,例如[10 20 30 40 50],注意,这不是列表,值之间没有逗号。

Series有一些常用方法:
函数名	含义
to_list()	将对象值转换为list列表。
to_dict()	将对象值转换为dict字典。
to_json()	将对象值转换为json字符串。
to_frame()	将对象值转换为DataFrame数据帧。
head(num)	从头部开始显示几行,参数num表示显示的行数,默认为5行。
tail(num)	从末尾开始显示几行,参数num表示显示的行数,默认为5行。
# 检测缺失数据的几个函数
isnull()                 判断是否为空,NaN表示空
pd.isnull(series)
notnull()                判断是否不为空
pd.notnull(series)

五、series的运算
(1)适用于NumPy的数组运算也适用于series
基本的算术运算
list1 = [10, 20, 30, 40, 50]
series = pd.Series(list1)
print(series + 5)
print(series - 5)
print(series * 2)
print(series / 2)
print(series // 4)  # 整除
print(series ** 2)
print(series % 2)

(2)series之间的运算
在运算中会自动对齐索引,注意是索引对齐,不是下标对齐
如果索引不完全匹配,Pandas会通过在缺少对应项的地方插入NaN(Not a Number)值来实现对齐,任何数和空运算结果为空




第二章、pandas数据结构之DataFrame
DataFrame数据帧
DataFrame(数据帧)是一个具有行列的二维数组,类似于表格数据。是一个表格型的数据结构,既有行索引也有列索引,
数据元素则是以二维结构存放的,它可以被看做由 Series 组成的字典(共同用一个索引)。

一、DataFrame的创建
pandas.DataFrame(data,index,columns [,dtype]):用于创建pandas.DataFrame对象。参数如下:

①参数data表示数据形式,如:数组、list、series、dict或DataFrame等;
②参数index表示唯一的行索引值,整数型索引为0到N-1(N为数据的长度);
③参数columns表示列索引值,取值与参数index类似;
④参数dtype用于数据类型,若没有设置,则pandas会自动推断并提供默认数据类型。

几种常见的创建DataFrame的方法:
1、直接填充值
df = pd.DataFrame(data=2, index=range(3), columns=['语文', '数学', '英语'])
print(df.values)
[[2 2 2]
 [2 2 2]
 [2 2 2]]
 
df = pd.DataFrame(data=2, index=range(3), columns=['语文', '数学', '英语'])
print(df)
   语文  数学  英语
0   2   2   2
1   2   2   2
2   2   2   2

2、从列表创建DataFrame,每个列表是一行,注意每个列表的元素个数要相等,不然会报错raise ValueError(err) from err       ValueError: 3 columns passed, passed data had 4 columns
list1 = [10, 20, 30]
list2 = ['a', 'b', 'c']
df = pd.DataFrame(data=[list1, list2], index=range(2), columns=['语文', '数学', '英语'])
print(df)
   语文  数学  英语
0  10  20  30
1   a   b   c

3、从列表创建DataFrame,每个列表是一列,要用zip函数转换下。
list1 = [10, 20, 30]
list2 = ['a', 'b', 'c']
df = pd.DataFrame(data=zip(list1, list2))
print(df)
    0  1
0  10  a
1  20  b
2  30  c

zip函数是一个内置函数,用于将多个可迭代对象(如列表、元组、字符串等)打包成一个元组的列表。每个元组包含的是原始可迭代对象中的对应位置的元素。
注意:
如果传入的可迭代对象长度不一致,zip函数会以最短的那个为准。
zip在Python 3中返回的是一个迭代器,因此通常需要转换(如使用list())才能直接查看结果。
list1 = [1, 2, 3]
list2 = ['a', 'b', 'c']
zipped = zip(list1, list2)
unzipped = zip(*zipped)          # *表示解压
print(list(zipped))              # [(1, 'a'), (2, 'b'), (3, 'c')]
print(list(unzipped))            # [(1, 2, 3), ('a', 'b', 'c')]


4、从字典创建DataFrame,key 会成为列名,value会成为对应的列
dict_data = {
    '日期': ['2021-08-21', '2021-08-22', '2021-08-23'],
    '温度': [25, 26, 50],
    '湿度': [81, 50, 56]
}
df1 = pandas.DataFrame(dict_data)
print(df1)
           日期  温度  湿度
0  2021-08-21  25  81
1  2021-08-22  26  50
2  2021-08-23  50  56


二、DataFrame的索引和切片,使用方法和Series,见上方Series里索引使用方法
DataFrame中有两种索引:
行索引(index):对应最左边那一竖列
list1 = [10, 20, 30]
list2 = ['a', 'b', 'c']
df = pd.DataFrame(data=[list1, list2], index=['A', 'B'])
print(df.loc['A'])
0    10
1    20
2    30
Name: A, dtype: object

列索引(columns):对应最上面那一横行,注意,单独对列进行索引没有loc[]和iloc[]方法
list1 = [10, 20, 30]
list2 = ['a', 'b', 'c']
df = pd.DataFrame(data=[list1, list2], index=['A', 'B'], columns=['小明', '小兰', '小白'])
print(df['小明'])
A    10
B     a
Name: 小明, dtype: object


行列一起索引:
获取 A C行,小明  小白列
list1 = [10, 20, 30]
list2 = ['a', 'b', 'c']
list3 = [40, 50, 60]
df = pd.DataFrame(data=[list1, list2, list3], index=['A', 'B', 'C'], columns=['小明', '小兰', '小白'])
print(df.loc[['A', 'C'], ['小明', '小白']])
   小明  小白
A  10  30
C  40  60

切片(可以用下标也可以用索引名和列名),取连续的行和连续的列或者连续的行列一般用切片方法:
list1 = [10, 20, 30]
list2 = ['a', 'b', 'c']
list3 = [40, 50, 60]
df = pd.DataFrame(data=[list1, list2, list3], index=['A', 'B', 'C'], columns=['小明', '小兰', '小白'])
print(df.loc['A':'B', '小明':'小兰'])
   小明  小兰
A  10  20
B   a   b

对列进行切片,语法df.loc[:, '小明':'小兰'],注意,行的那个 冒号不能不写,如果不写结果为空
list1 = [10, 20, 30]
list2 = ['a', 'b', 'c']
list3 = [40, 50, 60]
df = pd.DataFrame(data=[list1, list2, list3], index=['A', 'B', 'C'], columns=['小明', '小兰', '小白'])
print(df.loc[:, '小明':'小兰'])
   小明  小兰
A  10  20
B   a   b
C  40  50

对列进行切片,语法df.loc['A':'B', :],注意,列的那个 冒号 可写可不写
list1 = [10, 20, 30]
list2 = ['a', 'b', 'c']
list3 = [40, 50, 60]
df = pd.DataFrame(data=[list1, list2, list3], index=['A', 'B', 'C'], columns=['小明', '小兰', '小白'])
print(df.loc['A':'B', :])
   小明  小兰  小白
A  10  20  30
B   a   b   c

三、DataFrame的运算


四、pandas的多层索引
1、多层索引介绍
多层索引用在处理多维数据的时候用到,例如下面这种数据:
            北区             南区       
        电子产品   家居用品    电子产品   家居用品
2024-01  120000  80000  100000  70000
2024-02  150000  75000  110000  75000
2024-03  140000  90000  130000  85000

例子:
data = {
    ('北区', '电子产品'): [120000, 150000, 140000],
    ('北区', '家居用品'): [80000, 75000, 90000],
    ('南区', '电子产品'): [100000, 110000, 130000],
    ('南区', '家居用品'): [70000, 75000, 85000],
}

# 行索引(月份)
months = ['2024-01', '2024-02', '2024-03']

# 列创建多层索引,注意多层索引用的是元组
column = pd.MultiIndex.from_tuples([(region, product) for region in ['北区', '南区'] for product in ['电子产品', '家居用品']])

df_sales = pd.DataFrame(data, index=months, columns=column)
# df_sales.to_excel('./file/多层索引.xlsx')
print(df_sales.index)
结果是:
Index(['2024-01', '2024-02', '2024-03'], dtype='object')

print(df_sales.columns)   
结果是:
MultiIndex([('北区', '电子产品'),
            ('北区', '家居用品'),
            ('南区', '电子产品'),
            ('南区', '家居用品')],
           )


2、创建多层索引
2.1、使用set_index() 方法
参数说明
keys(旧版参数,推荐使用直接传入列名的方式代替): 指定要设置为索引的列名。
drop(默认为True): 如果为True,被设置为索引的列将从DataFrame中移除;如果为False,则列仍保留在DataFrame中。
append(默认为False): 如果为True,会在现有索引基础上添加新索引层次,而不是替换现有索引。
inplace(默认为False): 如果为True,直接在原DataFrame上修改,不返回新对象。
例如:
df = pd.DataFrame({
    'A': ['foo', 'bar', 'baz', 'foo'],
    'B': ['one', 'one', 'two', 'two'],
    'C': ['x', 'y', 'x', 'y'],
    'D': [1, 3, 2, 4]
})
# 设置A列为索引
single_index_df = df.set_index('A', drop=False)
single_index_df.index.name = None
print(single_index_df)

# 设置A B列为多层索引
single_index_df = df.set_index(['A', 'B'], drop=False)
single_index_df.index.name = None
print(single_index_df)


2.2、使用MultiIndex创建多层索引
1. 使用 pd.MultiIndex.from_tuples()
当你有一系列元组,每个元组代表一个唯一索引组合时,可以使用此方法:
tuples = [('a', 'x'), ('a', 'y'), ('b', 'x'), ('b', 'y')]
index = pd.MultiIndex.from_tuples(tuples, names=['Level1', 'Level2'])
df = pd.DataFrame({'Values': [1, 2, 3, 4]}, index=index)

2. 使用 pd.MultiIndex.from_arrays()
如果你有多个数组或列表,每个数组或列表对应一个索引级别,可以这样创建:
Python
levels = [['a', 'b', 'a', 'b'], ['x', 'x', 'y', 'y']]
labels = [0, 0, 1, 1]
index = pd.MultiIndex.from_arrays(levels, names=['Level1', 'Level2'])
df = pd.DataFrame({'Values': [1, 2, 3, 4]}, index=index)

3. 使用 pd.MultiIndex.from_product()
当你想要创建一个笛卡尔积的多层索引时,可以使用此方法:

Python
index = pd.MultiIndex.from_product([['a', 'b'], ['x', 'y']],
                                   names=['Level1', 'Level2'])
df = pd.DataFrame({'Values': [1, 2, 3, 4]}, index=index)

4. 隐式创建
在某些情况下,直接在构造DataFrame时指定多列作为索引,Pandas会自动创建多层索引

5. 在读取数据时指定
从CSV、Excel等文件读取数据时,如果文件中包含多级标题,可以通过pd.read_csv()或pd.read_excel()的header参数来指定多层索引:
# 假设Excel文件的第一行和第二行是多级表头
df = pd.read_excel('file.xlsx', header=[0, 1], index_col=0)

3、索引堆叠,stack()
stack()是一种数据重塑方法,它主要用于改变DataFrame的形状,将具有多级列索引的部分转换为行索引,从而将宽数据格式转换为长数据格式。
具体来说,当你有一个DataFrame,其列是多级索引,stack()操作会选取最里面一级列索引,
并将其变为行索引的一部分,形成一个新的二级索引(如果原来已经有二级索引,则会进一步嵌套)。


五、pandas合并操作 concat  append   merge
5.1、concat(连接)
concat 函数用于沿一个轴(通常是行或列)连接一系列对象。这对于简单地堆叠DataFrame或Series非常有用。
语法:pd.concat(objs, axis=0, join='outer', ignore_index=False, ...)
def concat(
    objs: Iterable[Series | DataFrame] | Mapping[HashableT, Series | DataFrame],
    *,
    axis: Axis = 0,
    join: str = "outer",
    ignore_index: bool = False,
    keys: Iterable[Hashable] | None = None,
    levels=None,
    names: list[HashableT] | None = None,
    verify_integrity: bool = False,
    sort: bool = False,
    copy: bool | None = None,
) -> DataFrame | Series

参数说明:
objs: 一个列表,包含要连接的DataFrame或Series对象。
axis: 指定连接的轴,0表示行(默认),1表示列。
join: 连接方式,默认为'outer',意味着保留所有索引;'inner'则只保留公共索引。
ignore_index: 如果设置为True,则忽略所有输入对象的索引,并为结果生成新的索引,行合并时才生效,列合并时不生效。
例子,列合并,注意列合并时行索引要保持一致:
df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],
                     'B': ['B0', 'B1', 'B2', 'B3']},
                    index=[4, 5, 6, 7])

df2 = pd.DataFrame({'C': ['A4', 'A5', 'A6', 'A7'],
                     'D': ['B4', 'B5', 'B6', 'B7']},
                   index=[8, 9, 10, 11])
df2.index = [4, 5 ,6, 7]

result = pd.concat([df1, df2], axis=1)
print(result)
    0   1   2   3
4  A0  B0  A4  B4
5  A1  B1  A5  B5
6  A2  B2  A6  B6
7  A3  B3  A7  B7

5.2、append
append 方法用于将另一个DataFrame的行或者另一个Seris添加到现有的DataFrame底部,类似于concat但更简单,主要用于行合并。
语法:df.append(other, ignore_index=False, verify_integrity=False, sort=None)
参数说明:
other: 要追加的DataFrame或Series。
ignore_index 和 verify_integrity 参数与concat相似。

5.3、merge
merge 用于基于一个或多个键(列)将两个DataFrame水平或垂直合并。这是数据库中的JOIN操作在Pandas中的体现。
语法:pandas.merge(left, right, how='inner', on=None, left_on=None, right_on=None,
             left_index=False, right_index=False, sort=False,
             suffixes=('_x', '_y'), copy=True, indicator=False,
             validate=None)-> DataFrame
             
def merge(
    left: DataFrame | Series,
    right: DataFrame | Series,
    how: MergeHow = "inner",
    on: IndexLabel | AnyArrayLike | None = None,
    left_on: IndexLabel | AnyArrayLike | None = None,
    right_on: IndexLabel | AnyArrayLike | None = None,
    left_index: bool = False,
    right_index: bool = False,
    sort: bool = False,
    suffixes: Suffixes = ("_x", "_y"),
    copy: bool | None = None,
    indicator: str | bool = False,
    validate: str | None = None,
) -> DataFrame
             
参数说明
left: 左侧的DataFrame或Seris对象。
right: 右侧的DataFrame或Seris对象。
how: 决定合并方式,默认为 'inner'。可选值包括:
    'inner': 只保留两个DataFrame中键相匹配的行。
    'left': 保留左侧DataFrame的所有行,右侧无匹配时填充NaN。
    'right': 保留右侧DataFrame的所有行,左侧无匹配时填充NaN。
    'outer': 合并所有行,左右无匹配时填充NaN。
on: 指定用于联接的列名列表。如果两个DataFrame有相同的列名,则可以直接指定该列名。
left_on 和 right_on: 分别指定左侧和右侧DataFrame用于联接的列名。当左右两侧列名不同时使用。
left_index 和 right_index: 如果设置为True,则使用左侧或右侧的索引作为联接键。
sort: 是否在合并后对结果进行排序,默认为False。
suffixes: 当左右DataFrame中有重名列但未被用作联接键时,用于区分它们的后缀。
copy: 默认True,总是复制数据。如果为False且可以避免复制则不复制。
indicator: 添加一个 _merge 列来标记行的来源,默认为False。可选值为 'True', 'False', 或者一个字符串,作为列名。
validate: 用于检查合并操作的有效性,如 'one_to_one', 'one_to_many', 'many_to_one', 'many_to_many'。

例子:
df1 = pd.DataFrame({'key': ['A', 'B', 'C', 'D'],
                    'value': [1, 2, 3, 4]})
df2 = pd.DataFrame({'key': ['B', 'D', 'E', 'F'],
                    'value_2': [5, 6, 7, 8]})

# 使用inner join 合并
merged_inner = pd.merge(df1, df2, on='key')
  key  value  value_2
0   B      2        5
1   D      4        6

# 使用outer join合并
merged_outer = pd.merge(df1, df2, on='key', how='outer')
  key  value  value_2
0   A    1.0      NaN
1   B    2.0      5.0
2   C    3.0      NaN
3   D    4.0      6.0
4   E    NaN      7.0
5   F    NaN      8.0
6   G    NaN      9.0

# 使用left_on  right_on 来合并
merge = pd.merge(left=df1, right=df2, left_on='key', right_on='key_2')
merge_new = merge.drop('key_2', axis=1)   # 注意,这个地方会把key_2列也打印出来,所以要删除key_2
print(merge_new)
print(merge)
  key  value  value_2
0   B      2        5
1   D      6        6
  key  value key_2  value_2
0   B      2     B        5
1   D      6     D        6

# 多个列做关联字段,会第一个与第一个关联,第二个与第二个关联
merge = pd.merge(left=df1, right=df2, left_on=['key', 'value'], right_on=['key_2', 'value_2'])
print(merge)
  key  value key_2  value_2
0   D      6     D        6


六、处理缺失值和重复值
6.1、删除缺失值的行或者列,dropna()函数,该函数主要用于根据值(如NaN值)来删除行或列,并不直接支持根据索引标签来删除行或列。
该函数会返回一个删除行或者列后的新对象
语法:df.dropna(axis=0, how='any', thresh=None, subset=None, inplace=False)
参数解释
axis:指定删除操作是在行(axis=0,默认值)还是列(axis=1)上进行。
how:指定删除的条件,可以是:
    'any'(默认值):只要某行或某列中有一个 NaN 值就删除。
    'all':只有当某行或某列中的所有值都是 NaN 时才删除。
thresh:指定每行或每列中非 NaN 值的最小数量。例如,thresh=3 表示至少有3个非NaN值的行或列会被保留。
subset:指定要考虑的列标签列表,仅在此列列表中的缺失值会影响到删除操作。
inplace:布尔值,默认为 False。如果设置为 True,则会在原始 DataFrame 或 Series 上直接进行修改,而不是返回一个新的对象。

6.2、填充缺失值
语法:df.fillna(value=None, method=None, axis=None, inplace=False, limit=None, downcast=None)
参数
value:用于替换缺失值的具体值。它可以是一个标量值(如整数、浮点数或字符串),一个列表、数组、Series 或 DataFrame。
如果 value 是一个 Series 或 DataFrame,它的索引需要与被填充的 DataFrame 的索引对齐。
method:指定填充缺失值的方法,可以是:
    'ffill''pad':前向填充,用前一个非NaN值填充缺失值。
    'bfill''backfill':后向填充,用后一个非NaN值填充缺失值。
默认为 None,表示不使用特定的填充方法。
axis:指定填充的方向,可以是 0(按列填充,默认值)或 1(按行填充)。
inplace:布尔值,默认为 False。如果设置为 True,则直接在原数据上修改,不返回新的对象。
limit:指定连续缺失值填充的最大数量。例如,如果 limit=1,则只填充每个NaN序列的第一个缺失值。
downcast:尝试向下转换(例如从 float64 转换为 int64)以节约内存,可选参数。

6.3、过滤缺失值的行列或者选择不含缺失值的行列
三个函数
all(axis=0),axis默认为0,表示行,为1 表示列
作用:当应用于布尔Series或DataFrame的一列或一行时,all() 会检查这一列或一行的所有值是否都为 True。
如果是,则返回 True;只要有任意一个值为 False(包括NaN,因为在布尔上下文中NaN被视为 False),则返回 False。

any(axis=0),axis默认为0,表示行,为1 表示列
作用:与 all() 相反,any() 检查至少有一个值为 True 的情况。如果有任何一个值为 True,
则返回 True;否则返回 False。同样地,NaN在这里也被视为 False。

sum(axis=0),axis默认为0,表示行,为1 表示列
作用:在常规情况下,sum() 计算数值的总和。但在布尔上下文中,它计数 True 的个数,False 和 NaN 被视为0。
因此,当你对一个布尔Series或DataFrame的一列或一行使用 sum() 时,它会返回 True 值的数量。

# 筛选出所有列都没有缺失值的行
df_no_missing = df[df.notnull().all(axis=1)]

# 筛选出所有行都没有缺失值的列
df_no_missing = df.columns[df.notnull().all(axis=0)]  # 结果得到的是列索引,如Index(['key', 'value'], dtype='object')

# 筛选出某列(例如 'A' 列)没有缺失值的行
df_A_not_missing = df[df['A'].notnull()]

# 获取所有行都没有缺失值的列
cols_no_missing = df.columns[df.notnull().all(axis=0)]
df_no_missing_cols = df[cols_no_missing]

6.4、处理重复值
df.duplicated()  # 找到完全重复的两行,注意是每列都重复的两行
df.drop_duplicates()  # 删除完全重复的行,保留第一行
df.drop_duplicates(keep='last')  # 删除完全重复的行,保留最后一行
df.alue_counts()   # 计数每个值出现的次数,但注意这个函数通常用于单列。
例如 value_counts = df['some_column'].value_counts()


6.5、数据处理几个函数,replace()  map()  rename()  reset_index()
语法:df.replace(to_replace, value, inplace=False, limit=None, regex=False, method='pad', axis=None)
返回一个替换后的对象
参数解释
to_replace:需要被替换的值或一系列值。它可以是单个值、列表、字典、正则表达式等。如果是字典形式,键是要被替换的值,值是替换后的值。
value:用于替换的新值。当 to_replace 是单个值时,这个参数指定替换的目标值。如果是字典或Series,则不需要此参数。
inplace:布尔值,默认为 False。如果设置为 True,则直接在原数据上修改,不会返回新的对象。
limit:替换的最大替换次数。这对于限制替换操作的次数很有用,比如只替换每个匹配项的前N个出现。
regex:布尔值,默认为 False。如果为 True,则 to_replace 将被解释为正则表达式。
method:仅在 limit 不为 None 且 to_replace 是NaN时使用,指定如何向前或向后填充。一般在处理缺失值时用到,如 'pad''bfill'。
axis:指定替换的方向,可以是 0(按列,默认)或 1(按行)。

语法:series.map(arg, na_action=None)
参数说明
arg:这是映射的依据,可以是字典、Series、函数或者一个可调用对象。如果提供的是字典,那么Series中的值将根据字典中的键值对进行替换。
如果提供的是函数或可调用对象,则会对Series中的每个元素应用该函数。
na_action:指定如何处理缺失值(NaN)。默认为 None,即保留缺失值不变。如果设置为 'ignore',则在映射过程中遇到缺失值时不进行任何操作。

# 创建一个示例Series
s = pd.Series(['apple', 'banana', 'orange', 'pear'])
# 定义一个映射字典
fruit_map = {'apple': 'fruit', 'banana': 'fruit', 'orange': 'fruit', 'pear': 'fruit'}
# 使用map()函数进行映射
mapped = s.map(fruit_map)
print(mapped)


语法:df.rename(columns=mapping, index=mapping, inplace=False, level=None, errors='ignore')
参数说明
columns(DataFrame专用): 用于重命名列的映射关系,通常是一个字典,键是旧列名,值是新列名。
index(通用): 用于重命名索引的映射关系,同样是一个字典,键是旧索引名,值是新索引名。
inplace:布尔值,默认为 False。如果设置为 True,则直接在原对象上修改,不会返回新的对象。
level:当索引是多层时,指定要重命名的级别。
errors:指定在遇到未在映射中定义的标签时的行为,可选值为 'ignore'(默认)、'raise''ignore'。
例子:
# 示例DataFrame
data = {'old_name_1': [1, 2, 3], 'old_name_2': [4, 5, 6]}
df = pd.DataFrame(data)
# 使用字典重命名列
renamed_df = df.rename(columns={'old_name_1': 'new_name_1', 'old_name_2': 'new_name_2'})
print(renamed_df)

# pandas 中的 reset_index() 函数用于重置DataFrame的索引
语法:df.reset_index(inplace=False, level=None, drop=False, col_level=0, col_fill='')
参数说明
inplace:布尔值,默认为 False。如果设置为 True,则直接在原DataFrame上进行修改,不返回新的DataFrame。
level:可选,用于指定重置哪一层或多层索引。如果不指定或为 None,则重置所有级别的索引。
drop:布尔值,默认为 False。如果设置为 True,则不会将旧的索引作为新列添加到DataFrame中,而是直接丢弃。
col_level:仅当索引是多级时有意义,用于指定将旧索引作为新列时,索引级别作为列级别的深度。默认为0,意味着使用最外层的级别。
col_fill:当 level 参数指定了一个或多个级别时,用于填充那些没有指定级别的列名。默认为空字符串。

例如:
data = {'A': [1, 2, 3], 'B': [4, 5, 6]}
df = pd.DataFrame(data, index=['a', 'b', 'c'])

# 重置索引,将原索引作为新列添加
resetted_df = df.reset_index()
print(resetted_df)

# 重置索引且不将原索引作为新列添加
resetted_df_drop = df.reset_index(drop=True)
print(resetted_df_drop)

七、apply() 函数和 applymap() 函数,transform() 函数
apply() 函数是一个非常强大的工具,它允许你对 DataFrame 或 Series 的每一行或每一列应用一个自定义函数。
这为数据处理提供了高度的灵活性,可以实现从简单计算到复杂数据转换的各种操作。
语法:
对于DataFrame:df.apply(func, axis=0, result_type=None, args=(), **kwargs)
对于Series:series.apply(func, convert_dtype=True, args=(), **kwargs)
参数说明
func:这是要应用的函数。它可以是自定义函数、Lambda表达式或者 numpy 的 ufunc(通用函数)。
axis:指定函数应用的方向。默认为 0,意味着沿列方向操作(即对每一行应用函数)。设置为 1 则沿行方向操作(对每一列应用函数)。
result_type:仅在 DataFrame 中使用,用于确定输出类型。可选值有 'expand'(默认,尝试将结果广播到与原DataFrame相同形状)、'reduce'(尝试将结果压缩为标量或Series)、'broadcast'(类似 'expand',但在某些情况下行为不同)。
convert_dtype:仅在 Series 中使用,指示是否转换结果的数据类型以保持与输入Series一致,默认为 True。
args 和 kwargs:额外的参数传递给 func。

注意事项:
当对大数据集使用 apply() 时,由于其逐行或逐列的迭代特性,可能不如向量化操作高效(如直接使用 pandas 内置函数或 numpy 函数)。
对于简单的数学运算或聚合操作,优先考虑使用 pandas 的内置方法(如 .sum(), .max(), .applymap() 等),因为它们通常更优化。
如果你的操作可以向量化,尽量避免使用 apply(),因为它在内部仍然是基于 Python 循环,相比底层 C 实现的函数会慢很多。
apply() 函数的强大之处在于它的灵活性,可以用来实现复杂的逻辑,尤其是在没有直接内置函数可以完成任务的情况下。


applymap() 函数用于将一个函数应用于DataFrame中每一个元素。与 apply() 函数相比,applymap() 主要针对元素级的操作,
适用于对DataFrame中的每个单独元素应用相同的函数,而不是整行或整列。
df.applymap(func)

transtorm() 函数


八、pandas 计算
8.1、有放回抽样和无放回抽样
抽样是一种减少数据量的方法,常见的有随机抽样和分层抽样。
1.随机抽样
按照数据会不会被放回参与下一次抽取,可以分为有放回抽样和无放回抽样。

语法:DataFrame.sample(n=None, frac=None, replace=False, weights=None, random_state=None, axis=None)
参数解释
n: 指定要抽取的样本数量。如果指定了frac,则忽略n。
frac: 抽取数据集的分数,例如frac=0.1表示抽取10%的数据。如果指定了n,则忽略frac。
replace: 布尔值,默认为False,表示不放回抽样。如果设置为True,则允许重复抽样。
weights: 可选参数,用于指定每行(或每列,如果axis=1)被抽中的概率。这可以是一个数组-like对象或Series,长度与数据集的行数相同。
random_state: 种子值或随机生成器,用于控制随机抽样的可重复性。如果给定一个整数,则会使用这个固定的种子。
axis: 指定抽样的轴,可以是0(默认,按行抽样)或1(按列抽样)。默认情况下,对行进行抽样。

8.2、常用聚合函数
sum(): 计算总和。
mean(): 计算平均值。
median(): 计算中位数。
min(): 获取最小值。
max(): 获取最大值。
count(): 计算非空值的数量。
std(): 计算标准差。
var(): 计算方差。
mad(): 计算平均绝对偏差。
prod(): 计算乘积。
quantile(): 计算分位数。
cumsum(): 计算累计和。c
cummin(): 计算累计最小值。
cummax(): 计算累计最大值。
describe(): 提供一系列汇总统计信息,包括计数、平均值、标准差、最小值、四分位数和最大值。
# 使用聚合函数
例如:
total_sales = sales_data['Amount'].sum()  
average_sale = sales_data['Amount'].mean()  
max_sale = sales_data['Amount'].max()  
min_sale = sales_data['Amount'].min()  

除了直接应用于单列(Series)上的这些基本聚合函数外,Pandas还提供了更灵活的聚合方式,比如使用agg()和apply()函数,
它们允许用户自定义聚合操作,甚至对多列同时应用不同的函数:
agg(): 应用一个或多个函数到数据的不同列上,可以传入函数名、函数列表或字典(键为列名,值为函数或函数列表)。
例如:
df.agg(['sum', 'mean'])
df.agg({'column1': 'sum', 'column2': ['min', 'max']})

8.3、分组聚合函数
data = {
    'Region': ['East', 'West', 'East', 'West', 'East', 'West'],
    'Product': ['A', 'A', 'B', 'B', 'A', 'B'],
    'Sales': [120, 200, 150, 300, 250, 180],
    'Quantity': [10, 15, 8, 12, 10, 9]
}

sales_df = pd.DataFrame(data)
# 对某列单一聚合,注意分组字段可以有多个,用列表表示,如 df.groupby(['Region', 'Product'])
grouped_sales = sales_df.groupby('Region')['Sales'].agg(['sum', 'mean'])
print(grouped_sales)
        sum        mean
Region                 
East    520  173.333333
West    680  226.666667

# 多个聚合函数及自定义函数
def custom_func(x):
    return x.quantile(0.9)  # 计算每组销售额的90%分位数

grouped_summary = sales_df.groupby('Region').agg({
    'Sales': ['sum', 'mean', custom_func],
    'Quantity': 'sum'
})


九、pandas加载数据
1、pandas 读取数据方式
数据类型                    说明               pandas读取方法
csv,tsv,txt      tsv是用tab分隔的文本文件        pd.read_csv
excel            微软xls或者xlsx文件            pd.read_excel
mysql            mysql数据库                   pd.read_sql


常用读写文件数据的函数有:
文件格式	    读取函数	    写入函数
xlsx	read_excel()	to_excel()
xls	    read_excel()	to_excel()
csv	    read_csv()	    to_csv()
tsv 	read_csv()	    to_csv()
json	read_json() 	to_json()
html	read_html()	    to_html()
sql	    read_sql()	    to_sql()

语法:
pd.read_csv(filepath_or_buffer=, sep=, delimiter=, header=, names=[], 
usecols=, skiprows, nrows=, na_values, encoding=,)
参数解释:
sep or delimiter:写一个就行,分隔符,默认是逗号,例如还可以是制表符 \t
header:指定哪一行作为列名,默认为 0,即第一行。如果文件没有列名行,可以设置为 None
names:如果文件没有列名行或者你想自定义列名,可以通过此参数提供一个列表来指定列名。
usecols:选择要读取的列,可以是列名的列表或列索引的列表。例如,usecols=[0, 1, 2] 或 usecols=['col1', 'col2', 'col3']。
skiprows:跳过文件开始的若干行。可以是一个整数(跳过多少行)或一个函数(返回 True 的行将被跳过)。
nrows:指定要读取的行数。如果只想读取前N行数据,可以使用这个参数。
na_values:指定哪些值应该被视为缺失值(NaN)。默认情况下,这包括空字符串和‘NA’等。
encoding:编码


pd.read_excel(io=, sheet_name=, engine=, )
参数解释:
io:要读取的 Excel 文件的路径、URL 或者是一个文件-like 对象。这是必填参数。
sheet_name:指定要读取的工作表名称或索引。默认为 0(第一个工作表)。可以是字符串(工作表名称)、整数(工作表索引)或列表(读取多个工作表到一个 DataFrame 字典中)。
engine:指定使用的Excel读取引擎,默认通常是 'openpyxl'(对于.xlsx文件)和 'xlrd'(对于.xls文件),
使用前要先下载但也可以显式指定。
其他参数和read_csv类似


2、pandas写入数据到excel等
注意,如果是想在同一个excel中写多个sheet,必须用ExcelWriter方法打开追加模式,否则第二个sheet会把第一个sheet覆盖
 if os.path.exists('../file/mysql长连接主键查询响应时间测试.xlsx'):
    with pd.ExcelWriter('../file/mysql长连接主键查询响应时间测试.xlsx', mode='a') as ew:
        df.to_excel(ew, index=False, sheet_name='8000W数据测试')
else:
    df.to_excel('../file/mysql长连接主键查询响应时间测试.xlsx', index=False, sheet_name='8000W数据测试')



十、pandas分箱操作
在Pandas中,进行数据分箱操作主要可以通过cut和qcut这两个函数实现,它们可以帮助我们将连续数据转换为分类数据,以便于分析和可视化

语法:pd.cut(x, bins, right=True, labels=None, retbins=False, precision=3, include_lowest=False, duplicates='raise')
x:要进行分箱的数组或Series。
bins:分箱的边界,可以是具体的数字列表,或者表示分箱数的整数。
right:默认为True,表示每个区间的右边是闭合的;False则左边闭合。
labels:可选参数,用于指定每个箱的标签。
retbins:是否返回分箱边界。
precision:控制输出的浮点数精度。
include_lowest:是否包含左端点的值。
duplicates:处理区间边界重复的情况。

语法:pd.qcut(x, q, duplicates='raise', labels=None, retbins=False, precision=3, include_lowest=True)
x:同上,要进行分箱的数据。
q:分箱的数量或者分位数的列表。
duplicates、labels、retbins、precision、include_lowest参数含义同cut函数。

区别
cut是基于数值区间进行分箱,更适用于你希望根据具体数值区间来分析数据的情况。
qcut是基于数据分布的频率进行等频分箱,适合于探索数据分布的模式,尤其是当数据分布不均匀时更为有效。

示例:
import pandas as pd
data = [x*2 for x in range(1, 21)]
df = pd.DataFrame(data=data, columns=['a'])

# 使用cut进行等距分箱
bins = [0, 10, 20, 30]
df['a_cut'] = pd.cut(df['a'], bins=bins)

# 使用qcut进行等频分箱
df['a_qcut'] = pd.qcut(df['a'], q=4)


十一、pandas时间序列
Timestamp 是 Pandas 中用于表示单个时间点的类,它是 numpy.datetime64 的子类,与 Python 的 datetime.datetime 类兼容。可以精确到纳秒级别。

创建:可以通过多种方式创建 Timestamp 对象,例如直接从字符串转换,或者使用特定的日期时间构造函数。
示例:
from pandas import Timestamp
t = Timestamp('2024-06-24 12:00:00')

# 生成时间序列:pd.date_range() 函数可以用来生成一个时间序列区间,通过指定开始日期、结束日期、周期频率等参数。
语法:pd.date_range(start=None, end=None, periods=None, freq='D', tz=None, normalize=False, name=None, closed=None, **kwargs)
参数解释:
start:时间序列的起始日期,可以是字符串或 Timestamp 对象。默认为 None。
end:时间序列的结束日期,与 start 类似。start 和 end 两者至少提供一个,但不能同时为 None。
periods:生成的日期数量,默认为 None。如果提供了 periods,那么 start 和 end 将根据需要被推断或忽略。
freq:日期或时间间隔的频率字符串,比如 'D' 表示日频,'W' 表示周频,'M' 表示月频等。这是最重要的参数之一,决定了序列的密度。
tz:指定时区。
normalize:布尔值,默认为 False。如果为 True,则将每个时间戳的小时、分钟、秒和微秒部分设置为零,即每天的开始时间(通常是午夜)。
name:结果 Series 的名称。
closed:定义区间是开区间还是闭区间,以及区间的哪一端是封闭的。可选值为 'right' (默认)、'left''both''neither'。
**kwargs:其他传递给底层频率对象的参数。
示例:
pd.date_range(start='2024-01-01', end='2024-06-30', freq='M')  # 按月生成
时间频率(freq)
频率字符串:Pandas 支持丰富的频率字符串(如 'D' 日、'W' 周、'M' 月等),用于定义时间序列的周期性。

# 重采样与频率转换(resample)
可以使用 resample() 方法对时间序列数据进行重采样,重采样允许用户将时间序列数据从一个时间频率转换到另一个频率,比如将日频数据转换为月频
示例:
ts.resample('M')


十二、pandas绘图
Pandas 的 plot 函数是一个非常强大的工具,用于数据可视化,它基于 Matplotlib 库进行了封装,使得直接对 DataFrame 或 Series 进行绘图变得简单直观。
语法:
pd.DataFrame.plot()
pd.Series.plot()
参数说明
kind:指定图表类型,默认为 'line'(折线图),
其他常见类型包括 'bar'(柱状图),'barh'(水平柱状图),'hist'(直方图),'box'(箱形图),'scatter'(散点图),'area'面积图
,'pie'饼图等。
x,y:分别指定 x 轴和 y 轴的列名。如果不指定,默认使用 DataFrame 的索引作为 x 轴。
title:图表标题。
xlabel,ylabel:x 轴和 y 轴的标签。
grid:是否显示网格线,默认为 None,即根据图表类型自动决定。
legend:是否显示图例,默认为 True。
color:线条或柱子的颜色,可以是颜色名称或颜色代码。
style:指定线型或标记样式,如 '--' 表示虚线。
alpha:透明度,0.0(完全透明)到 1.0(完全不透明)之间。
figsize:图表大小,以英寸为单位,例如 (10, 6)。

示例:
import pandas as pd
import matplotlib.pyplot as plt
df = pd.DataFrame({
    'sales': [3, 3, 3, 9, 10, 6],
    'signups': [4, 5, 6, 10, 12, 13],
    'visits': [20, 42, 28, 62, 81, 50],
}, index=pd.date_range(start='2018/01/01', end='2018/07/01', freq='M'))

df.plot(kind='bar')
plt.show()

posted @   有形无形  阅读(51)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示