函数
1、常用的统计学函数
函数名称 | 描述说明 |
---|---|
count() | 统计某个非空值的数量 |
sum() | 求和 |
mean() | 求均值 |
median() | 求中位数 |
std() | 求标准差 |
min() | 求最小值 |
max() | 求最大值 |
abs() | 求绝对值 |
prod() | 求所有数值的乘积 |
注意:numpy的方差默认为总体方差,pandas默认为样本方差
2、重置索引
重置索引(reindex)可以更改原 DataFrame 的行标签或列标签,并使更改后的行、列标签与 DataFrame 中的数据逐一匹配。通过重置索引操作,您可以完成对现有数据的重新排序。如果重置的索引标签在原 DataFrame 中不存在,那么该标签对应的元素值将全部填充为 NaN。
2.1 reindex
reindex() 方法用于重新索引 DataFrame 或 Series 对象。重新索引意味着根据新的索引标签重新排列数据,并填充缺失值。如果重置的索引标签在原 DataFrame 中不存在,那么该标签对应的元素值将全部填充为 NaN。
语法:
DataFrame.reindex(labels=None, index=None, columns=None, axis=None, method=None, copy=True, level=None, fill_value=np.nan, limit=None, tolerance=None)
总结
-
method='ffill'
在重新索引时,用前面的有效值填充后续缺失值。 -
确保索引有序(单调),否则填充可能失败或结果异常。
-
适用于时间序列重采样、扩展索引范围等场景,能有效保持数据连续性。
参数:
-
labels:
-
类型:数组或列表,默认为 None。
-
描述:新的索引标签。
-
-
index:
-
类型:数组或列表,默认为 None。
-
描述:新的行索引标签。
-
-
columns:
-
类型:数组或列表,默认为 None。
-
描述:新的列索引标签。
-
-
axis:
-
类型:整数或字符串,默认为 None。
-
描述:指定重新索引的轴。0 或 'index' 表示行,1 或 'columns' 表示列。
-
-
method:
-
类型:字符串,默认为 None。
-
描述:用于填充缺失值的方法。可选值包括 'ffill'(前向填充)、'bfill'(后向填充)等。
-
-
copy:
-
类型:布尔值,默认为 True。
-
描述:是否返回新的 DataFrame 或 Series。
-
-
level:
-
类型:整数或级别名称,默认为 None。
-
描述:用于多级索引(MultiIndex),指定要重新索引的级别。
-
-
fill_value:
-
类型:标量,默认为 np.nan。
-
描述:用于填充缺失值的值。
-
-
limit:
-
类型:整数,默认为 None。
-
描述:指定连续填充的最大数量。
-
-
tolerance:
-
类型:标量或字典,默认为 None。
-
描述:指定重新索引时的容差。
-
案例:ffill()方法
# 创建一个示例 DataFrame
data = {
'A': [1, 2, 3],
'B': [4, 5, 6],
'C': [7, 8, 9]
}
df = pd.DataFrame(data, index=['a', 'b', 'c'])
# 重新索引行
new_index = ['a', 'b', 'c', 'd']
df_reindexed = df.reindex(new_index)
print(df_reindexed)
# 重新索引列
new_columns = ['A', 'B', 'C', 'D']
df_reindexed = df.reindex(columns=new_columns)
print(df_reindexed)
# 重新索引行,并使用前向填充
# 新的行索引 ['a', 'b', 'c', 'd'] 包含了原索引中不存在的标签 'd',使用 method='ffill' 进行前向填充,因此 'd' 对应的行填充了前一行的值。
new_index = ['a', 'b', 'c', 'd']
df_reindexed = df.reindex(new_index, method='ffill')
print(df_reindexed)
# 重新索引行,并使用指定的值填充缺失值
new_index = ['a', 'b', 'c', 'd']
df_reindexed = df.reindex(new_index, fill_value=0)
print(df_reindexed)
2.2 reindex_like
reindex_like 方法用于将一个 DataFrame 或 Series 的索引重新排列,使其与另一个 DataFrame 或 Series 的索引相匹配。如果在重新索引的过程中,新的索引与原始索引不完全匹配,那么不匹配的位置将会被填充为 NaN 值。
语法:
DataFrame.reindex_like(other, method=None, copy=True, limit=None, tolerance=None)
参数:
-
other:
-
类型:DataFrame 或 Series。
-
描述:用于对齐索引和列的参考对象。
-
-
method:
-
类型:字符串,默认为 None。
-
描述:用于填充缺失值的方法。可选值包括 'ffill'(前向填充)、'bfill'(后向填充)等。
-
-
copy:
-
类型:布尔值,默认为 True。
-
描述:是否返回新的 DataFrame 或 Series。
-
-
limit:
-
类型:整数,默认为 None。
-
描述:指定连续填充的最大数量。
-
-
tolerance:
-
类型:标量或字典,默认为 None。
-
描述:指定重新索引时的容差。
-
案例:对齐行索引
import pandas as pd
# 创建两个示例 DataFrame
df1 = pd.DataFrame({
'A': [1, 2, 3],
'B': [4, 5, 6]
}, index=['a', 'b', 'c'])
df2 = pd.DataFrame({
'A': [7, 8, 9],
'B': [10, 11, 12]
}, index=['b', 'c', 'd'])
# 使用 reindex_like 对齐 df1 的行索引到 df2
# df1 的行索引被重新索引为 df2 的行索引,因此 df1 中不存在的行索引 'd' 对应的行填充了 NaN。
df1_reindexed = df1.reindex_like(df2)
print(df1_reindexed)
# 输出:
A B
b 2.0 5.0
c 3.0 6.0
d NaN NaN
3、遍历
对于 Series 而言,您可以把它当做一维数组进行遍历操作;而像 DataFrame 这种二维数据表结构,则类似于遍历 Python 字典
Series 可直接获取相应的 value,而 DataFrame 则会获取列标签
案例:
import pandas as pd
series_data = pd.Series(['a','b','c','d','e','f',None])
print('Series:')
for item in series_data:
print(item, end=' ')
#输出:
a b c d e f None
3.1 Series遍历
使用 items()
import pandas as pd
# 创建一个示例 Series
series = pd.Series([1, 2, 3], index=['a', 'b', 'c'])
for index, value in series.items():
print(f"Index: {index}, Value: {value}")
#输出:
Index: a, Value: 1
Index: b, Value: 2
Index: c, Value: 3
使用 index 属性
import pandas as pd
# 创建一个示例 Series
series = pd.Series([1, 2, 3], index=['a', 'b', 'c'])
# 遍历索引
for index in series.index:
print(f"Index: {index}, Value: {series[index]}")
#输出:
Index: a, Value: 1
Index: b, Value: 2
Index: c, Value: 3
使用 values 属性
import pandas as pd
# 创建一个示例 Series
series = pd.Series([1, 2, 3], index=['a', 'b', 'c'])
# 遍历值
for value in series.values:
print(f"Value: {value}")
# 输出:
Value: 1
Value: 2
Value: 3
3.2 DataFrame 遍历
dataFrame_data = pd.DataFrame({
'one': pd.Series([1, 2, 3], index=['a', 'b', 'c']),
'two': pd.Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd'])
})
# 遍历dataframe得到的是列标签
print('DataFrame:')
for item in dataFrame_data:
print(item, end=' ')
#输出:
one two
迭代器返回的是原数据的副本
遍历行
iterrows() 方法用于遍历 DataFrame 的行,返回一个包含索引和行的迭代器。
案例:
import pandas as pd
# 创建一个示例 DataFrame
data = {
'A': [1, 2, 3],
'B': [4, 5, 6],
'C': [7, 8, 9]
}
df = pd.DataFrame(data, index=['a', 'b', 'c'])
# 使用 iterrows() 遍历行
for index, row in df.iterrows():
print(f"Index: {index}, Row: {row}")
# 输出:
Index: a, Row: A 1
B 4
C 7
Name: a, dtype: int64
Index: b, Row: A 2
B 5
C 8
Name: b, dtype: int64
Index: c, Row: A 3
B 6
C 9
Name: c, dtype: int64
itertuples() 方法用于遍历 DataFrame 的行,返回一个包含行数据的命名元组。
案例:
import pandas as pd
# 创建一个示例 DataFrame
data = {
'A': [1, 2, 3],
'B': [4, 5, 6],
'C': [7, 8, 9]
}
df = pd.DataFrame(data, index=['a', 'b', 'c'])
# 使用 itertuples() 遍历行
for row in df.itertuples():
print(row)
for i in row:
print(i)
#输出:
Pandas(Index='a', A=1, B=4, C=7)
a
1
4
7
Pandas(Index='b', A=2, B=5, C=8)
b
2
5
8
Pandas(Index='c', A=3, B=6, C=9)
c
3
6
9
# 忽略索引
for row in df.itertuples(index=False):
print(row)
for i in row:
print(i)
当处理大型数据集时,应尽量避免使用 iterrows(),因为它的性能相对较差。
itertuples() 是遍历 DataFrame 的推荐方法,因为它在速度和内存使用上都更高效。
遍历列
items() 方法用于遍历 DataFrame 的列,返回一个包含列名和列数据的迭代器。
4、排序
4.1 sort_index
sort_index 方法用于对 DataFrame 或 Series 的索引进行排序。
语法:
DataFrame.sort_index(axis=0, ascending=True, inplace=False)
Series.sort_index(axis=0, ascending=True, inplace=False)
参数:
-
axis:指定要排序的轴。默认为 0,表示按行索引排序。如果设置为 1,将按列索引排序。
-
ascending:布尔值,指定是升序排序(True)还是降序排序(False)。
-
inplace:布尔值,指定是否在原地修改数据。如果为 True,则会修改原始数据;如果为 False,则返回一个新的排序后的对象。
import pandas as pd
# 创建一个示例 DataFrame
data = {
'A': [1, 2, 3],
'B': [4, 5, 6],
'C': [7, 8, 9]
}
df = pd.DataFrame(data, index=['b', 'c', 'a'])
# 按行索引标签排序,不对对应的值排序
df_sorted = df.sort_index()
#输出:
A B C
a 3 6 9
b 1 4 7
c 2 5 8
#按列索引标签降序排序
df_sorted = df.sort_index(axis=1,ascending=False)
print(df_sorted)
# 输出:
C B A
b 7 4 1
c 8 5 2
a 9 6 3
4.2 sort_values
sort_values 方法用于根据一个或多个列的值对 DataFrame 进行排序。
语法:
DataFrame.sort_values(by, axis=0, ascending=True, inplace=False, kind='quicksort', na_position='last')
参数:
-
by:列的标签或列的标签列表。指定要排序的列。
-
axis:指定沿着哪个轴排序。默认为 0,表示按行排序。如果设置为 1,将按列排序。
-
ascending:布尔值或布尔值列表,指定是升序排序(True)还是降序排序(False)。可以为每个列指定不同的排序方向。
-
inplace:布尔值,指定是否在原地修改数据。如果为 True,则会修改原始数据;如果为 False,则返回一个新的排序后的对象。
-
kind:排序算法。默认为 'quicksort',也可以选择 'mergesort'(归并排序) 或 'heapsort'(堆排序)。
-
na_position:指定缺失值(NaN)的位置。可以是 'first' 或 'last'。
import pandas as pd
# 创建一个示例 DataFrame
data = {
'A': [3, 2, 1],
'B': [6, 5, 4],
'C': [9, 8, 7]
}
df = pd.DataFrame(data, index=['b', 'c', 'a'])
# 按列 'A' 排序
df_sorted = df.sort_values(by='A')
print(df_sorted)
# 按列 'A' 和 'B' 排序
df_sorted = df.sort_values(by=['A', 'B'])
print(df_sorted)
# 按列 'A' 降序排序
df_sorted = df.sort_values(by='A', ascending=False)
print(df_sorted)
# 按列 'A' 和 'B' 排序,先按A列降序排序,如果A列中值相同则按B列升序排序
df = pd.DataFrame({
'Name': ['Alice', 'Bob', 'Charlie', 'David', 'Eve'],
'Age': [25, 30, 25, 35, 30],
'Score': [85, 90, 80, 95, 88]
})
df_sorted = df.sort_values(by=['Age', 'Score'], ascending=[False, True])
print(df_sorted)
5、去重
drop_duplicates 方法用于删除 DataFrame 或 Series 中的重复行或元素。
语法:
drop_duplicates(by=None, subset=None, keep='first', inplace=False)
Series.drop_duplicates(keep='first', inplace=False)
参数:
-
by:用于标识重复项的列名或列名列表。如果未指定,则使用所有列。
-
subset:与 by 类似,但用于指定列的子集。
-
keep:指定如何处理重复项。可以是:
-
'first':保留第一个出现的重复项(默认值)。
-
'last':保留最后一个出现的重复项。
-
False:删除所有重复项。
-
-
inplace:布尔值,指定是否在原地修改数据。如果为 True,则会修改原始数据;如果为 False,则返回一个新的删除重复项后的对象。
import pandas as pd
# 创建一个示例 DataFrame
data = {
'A': [1, 2, 2, 3],
'B': [4, 5, 5, 6],
'C': [7, 8, 8, 9]
}
df = pd.DataFrame(data)
# 删除所有列的重复行,默认保留第一个出现的重复项
df_unique = df.drop_duplicates()
print(df_unique)
# 删除重复行,保留最后一个出现的重复项
df_unique = df.drop_duplicates(keep='last')
print(df_unique)
6、分组
6.1 groupby
groupby 方法用于对数据进行分组操作,这是数据分析中非常常见的一个步骤。通过 groupby,你可以将数据集按照某个列(或多个列)的值分组,然后对每个组应用聚合函数,比如求和、平均值、最大值等。
语法:
DataFrame.groupby(by, axis=0, level=None, as_index=True, sort=True, group_keys=True, squeeze=False, observed=False, **kwargs)
参数:
-
by:用于分组的列名或列名列表。
-
axis:指定沿着哪个轴进行分组。默认为 0,表示按行分组。
-
level:用于分组的 MultiIndex 的级别。
-
as_index:布尔值,指定分组后索引是否保留。如果为 True,则分组列将成为结果的索引;如果为 False,则返回一个列包含分组信息的 DataFrame。
-
sort:布尔值,指定在分组操作中是否对数据进行排序。默认为 True。
-
group_keys:布尔值,指定是否在结果中添加组键。
-
squeeze:布尔值,如果为 True,并且分组结果返回一个元素,则返回该元素而不是单列 DataFrame。
-
observed:布尔值,如果为 True,则只考虑数据中出现的标签。
transform用于在分组操作中对每个组内的数据进行转换,并将结果合并回原始 DataFrame。
import pandas as pd
# 创建一个示例 DataFrame
data = {
'A': ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'],
'B': ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'],
'C': [1, 2, 3, 4, 5, 6, 7, 8],
'D': [10, 20, 30, 40, 50, 60, 70, 80]
}
df = pd.DataFrame(data)
# 按列 'A' 分组
grouped = df.groupby('A')
# 查看分组结果
for name, group in grouped:
print(f"Group: {name}")
print(group)
print()
mean = df.groupby(['A'])['C'].mean()
print(mean)
#输出:
C D
A
bar 4.0 40.0
foo 4.8 48.0
mean = grouped['C'].mean()
print(mean)
#输出:
A
bar 4.0
foo 4.8
# 在分组内根据C列求平均值
# transform用于在分组操作中对每个组内的数据进行转换,并将结果合并回原始 DataFrame。
mean = grouped['C'].transform(lambda x: x.mean())
df['C_mean'] = mean
print(df)
#输出:
A B C D C_mean
0 foo one 1 10 4.8
1 bar one 2 20 4.0
2 foo two 3 30 4.8
3 bar three 4 40 4.0
4 foo two 5 50 4.8
5 bar two 6 60 4.0
6 foo one 7 70 4.8
7 foo three 8 80 4.8
get_group()
方法在 Python 的 pandas
库中是一个非常实用的方法,它主要用于从 GroupBy
对象中提取特定的分组数据。
import pandas as pd
# 创建一个示例 DataFrame
data = {
'Name': ['Alice', 'Bob', 'Charlie', 'Alice', 'Bob'],
'Score': [85, 90, 78, 92, 88]
}
df = pd.DataFrame(data)
# 按 'Name' 列进行分组
grouped = df.groupby('Name')
# 获取 'Alice' 这个分组的数据
alice_group = grouped.get_group('Alice')
print(alice_group)
6.2 filter
通过 filter() 函数可以实现数据的筛选,该函数根据定义的条件过滤数据并返回一个新的数据集
import pandas as pd
# 创建一个示例 DataFrame
data = {
'A': ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'],
'B': ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'],
'C': [1, 2, 3, 4, 5, 6, 7, 8],
'D': [10, 20, 30, 40, 50, 60, 70, 80]
}
df = pd.DataFrame(data)
# 按列 'A' 分组,并过滤掉列 'C' 的平均值小于 4 的组
filtered = df.groupby('A').filter(lambda x: x['C'].mean() >= 4)
print(filtered)
7、合并
merge 函数用于将两个 DataFrame 对象根据一个或多个键进行合并,类似于 SQL 中的 JOIN 操作。这个方法非常适合用来基于某些共同字段将不同数据源的数据组合在一起,最后拼接成一个新的 DataFrame 数据表。
函数:
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)
参数:
-
left:左侧的 DataFrame 对象。
-
right:右侧的 DataFrame 对象。
-
how:合并方式,可以是 'inner'、'outer'、'left' 或 'right'。默认为 'inner'。
-
'inner':内连接,返回两个 DataFrame 共有的键。
-
-
'outer':外连接,返回两个 DataFrame 的所有键。
-
'left':左连接,返回左侧 DataFrame 的所有键,以及右侧 DataFrame 匹配的键。
-
'right':右连接,返回右侧 DataFrame 的所有键,以及左侧 DataFrame 匹配的键。
-
-
on:用于连接的列名。如果未指定,则使用两个 DataFrame 中相同的列名。
-
left_on 和 right_on:分别指定左侧和右侧 DataFrame 的连接列名。
-
left_index 和 right_index:布尔值,指定是否使用索引作为连接键。
-
sort:布尔值,指定是否在合并后对结果进行排序。
-
suffixes:一个元组,指定当列名冲突时,右侧和左侧 DataFrame 的后缀。
-
copy:布尔值,指定是否返回一个新的 DataFrame。如果为 False,则可能修改原始 DataFrame。
-
indicator:布尔值,如果为 True,则在结果中添加一个名为 __merge 的列,指示每行是如何合并的。
-
validate:验证合并是否符合特定的模式。
案例1:内连接
import pandas as pd
# 创建两个示例 DataFrame
left = pd.DataFrame({
'key': ['K0', 'K1', 'K2', 'K3'],
'A': ['A0', 'A1', 'A2', 'A3'],
'B': ['B0', 'B1', 'B2', 'B3']
})
right = pd.DataFrame({
'key': ['K0', 'K1', 'K2', 'K4'],
'C': ['C0', 'C1', 'C2', 'C3'],
'D': ['D0', 'D1', 'D2', 'D3']
})
# 内连接
result = pd.merge(left, right, on='key')
print(result)
#输出:K3、K4被忽略
key A B C D
0 K0 A0 B0 C0 D0
1 K1 A1 B1 C1 D1
2 K2 A2 B2 C2 D2
案例1:外连接
import pandas as pd
# 创建两个示例 DataFrame
left = pd.DataFrame({
'key': ['K0', 'K1', 'K2', 'K3'],
'A': ['A0', 'A1', 'A2', 'A3'],
'B': ['B0', 'B1', 'B2', 'B3']
})
right = pd.DataFrame({
'key': ['K0', 'K1', 'K2', 'K4'],
'C': ['C0', 'C1', 'C2', 'C3'],
'D': ['D0', 'D1', 'D2', 'D3']
})
# 左连接,以左侧表为准
result = pd.merge(left, right, on='key', how='left')
print(result)
# 输出:
key A B C D
0 K0 A0 B0 C0 D0
1 K1 A1 B1 C1 D1
2 K2 A2 B2 C2 D2
3 K3 A3 B3 NaN NaN
8、随机抽样
语法:
DataFrame.sample(n=None, frac=None, replace=False, weights=None, random_state=None, axis=None)
参数:
-
n:要抽取的行数
-
frac:抽取的比例,比如 frac=0.5,代表抽取总体数据的50%
-
replace:布尔值参数,表示是否以有放回抽样的方式进行选择,默认为 False,取出数据后不再放回
-
weights:可选参数,代表每个样本的权重值,参数值是字符串或者数组
-
random_state:可选参数,控制随机状态,默认为 None,表示随机数据不会重复;若为 1 表示会取得重复数据
-
axis:表示在哪个方向上抽取数据(axis=1 表示列/axis=0 表示行)
案例:
import pandas as pd
def sample_test():
df = pd.DataFrame({
"company": ['百度', '阿里', '腾讯'],
"salary": [43000, 24000, 40000],
"age": [25, 35, 49]
})
print('随机选择两行:')
print(df.sample(n=2, axis=0))
print('随机选择一列:')
print(df.sample(n=1, axis=1))
print('总体的50%:')
print(df.sample(axis=0, frac=0.5))
9、空值处理
9.1 检测空值
isnull()用于检测 DataFrame 或 Series 中的空值,返回一个布尔值的 DataFrame 或 Series。
notnull()用于检测 DataFrame 或 Series 中的非空值,返回一个布尔值的 DataFrame 或 Series。
案例:
import pandas as pd
import numpy as np
# 创建一个包含空值的示例 DataFrame
data = {
'A': [1, 2, np.nan, 4],
'B': [5, np.nan, np.nan, 8],
'C': [9, 10, 11, 12]
}
df = pd.DataFrame(data)
# 检测空值
is_null = df.isnull()
print(is_null)
# 检测非空值
not_null = df.notnull()
print(not_null)
9.2 填充空值
fillna() 方法用于填充 DataFrame 或 Series 中的空值。
案例:
# 创建一个包含空值的示例 DataFrame
data = {
'A': [1, 2, np.nan, 4],
'B': [5, np.nan, np.nan, 8],
'C': [9, 10, 11, 12]
}
df = pd.DataFrame(data)
# 用 0 填充空值
df_filled = df.fillna(0)
print(df_filled)
9.3 删除空值
dropna() 方法用于删除 DataFrame 或 Series 中的空值。
DataFrame.dropna(axis=0, how='any', thresh=None, subset=None, inplace=False)
参数解释
-
axis
:指定删除缺失值的方向,取值为0
或'index'
表示按行删除(默认值),取值为1
或'columns'
表示按列删除。 -
how
:可选参数,仅适用于DataFrame
,用于指定删除行或列的条件。取值为'any'
表示只要行或列中有一个缺失值就删除(默认值);取值为'all'
表示只有当行或列中的所有值都是缺失值时才删除。 -
thresh
:可选参数,仅适用于DataFrame
,指定保留行或列所需的非缺失值的最小数量。如果某行或某列的非缺失值数量小于thresh
,则将其删除。 -
subset
:可选参数,仅适用于DataFrame
,指定要考虑的列或行的标签列表。只在这些指定的列或行中检查缺失值。 -
inplace
:布尔值,指定是否在原对象上进行修改。如果为True
,则直接修改原对象并返回None
;如果为False
,则返回一个新的对象,原对象保持不变(默认值为False
)。
案例:
# 创建一个包含空值的示例 DataFrame
data = {
'A': [1, 2, np.nan, 4],
'B': [5, np.nan, np.nan, 8],
'C': [9, 10, 11, 12]
}
df = pd.DataFrame(data)
# 删除包含空值的行
df_dropped = df.dropna()
print(df_dropped)
#输出:
A B C
0 1.0 5.0 9
3 4.0 8.0 12
# 删除包含空值的列
df_dropped = df.dropna(axis=1)
print(df_dropped)
#输出:
C
0 9
1 10
2 11
3 12