DataFrame的遍历、排序、去重与分组

文章发布时间:

最后更新时间:

文章总字数:
2.2k

预计阅读时间:
10 分钟

一.遍历

1.1 series遍历

1
2
3
4
5
6
import pandas as pd

s = pd.Series(['a','b','c','d','e','f'],index=[1,2,3,4,5,6])

for i in s:
print(i)

结果:

1
2
3
4
5
6
a
b
c
d
e
f

可见,遍历series会直接拿到其中的值。

1.2 DataFrame遍历

1.2.1 直接遍历

1
2
3
4
5
6
7
8
9
10
import pandas as pd
data = {
'name': ['Alice', 'Bob', 'Charlie'],
'age': [25, 30, 35],
'score': [85, 90, 88]
}

df = pd.DataFrame(data)
for i in df:
print(i)

结果:

1
2
3
name
age
score

可见直接遍历DataFrame时只会得到列标签,无法得到数据

那怎么才能得到其中的数据呢?

1.2.2 遍历行

itertuples() 方法用于遍历 DataFrame 的行,返回一个包含行数据的命名元组。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import pandas as pd
data = {
'name': ['Alice', 'Bob', 'Charlie'],
'age': [25, 30, 35],
'score': [85, 90, 88]
}

df = pd.DataFrame(data)

# 取出DataFrame的每一行数据,同时不打印行索引
h = df.itertuples(index = False)

for i in h:
print(i)

结果:

1
2
3
Pandas(name='Alice', age=25, score=85)
Pandas(name='Bob', age=30, score=90)
Pandas(name='Charlie', age=35, score=88)

1.2.3 遍历列

items() 方法用于遍历 DataFrame 的列,返回一个包含列名和列数据的迭代器。

1
2
3
4
5
6
7
8
9
10
11
12
import pandas as pd
data = {
'name': ['Alice', 'Bob', 'Charlie'],
'age': [25, 30, 35],
'score': [85, 90, 88]
}

df = pd.DataFrame(data)

l = df.items()
for i in l:
print(i)

结果:

1
2
3
4
5
6
7
8
9
10
11
12
('name', 0      Alice
1 Bob
2 Charlie
Name: name, dtype: object)
('age', 0 25
1 30
2 35
Name: age, dtype: int64)
('score', 0 85
1 90
2 88
Name: score, dtype: int64)

1.2.4 使用属性遍历

loc 和 iloc 方法可以用于按索引或位置遍历 DataFrame 的行和列。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import pandas as pd
data = {
'name': ['Alice', 'Bob', 'Charlie'],
'age': [25, 30, 35],
'score': [85, 90, 88]
}
df = pd.DataFrame(data)

# 取出行和列标签
h = df.index
l = df.columns

# 遍历行
for i in h:
print(df.loc[i])

print()

# 遍历列
for i in l:
# 或者直接写df[i]
print(df.loc[...,i])

结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
name     Alice
age 25
score 85
Name: 0, dtype: object
name Bob
age 30
score 90
Name: 1, dtype: object
name Charlie
age 35
score 88
Name: 2, dtype: object

0 Alice
1 Bob
2 Charlie
Name: name, dtype: object
0 25
1 30
2 35
Name: age, dtype: int64
0 85
1 90
2 88
Name: score, dtype: int64
1
2
3
4
# 一起遍历
for i in h:
for j in l:
print(df.loc[i,j])

结果:

1
2
3
4
5
6
7
8
9
Alice
25
85
Bob
30
90
Charlie
35
88

二.排序

2.1 sort_index

sort_index 方法用于对 DataFrame 或 Series 的索引进行排序。

1
2
3
4
5
6
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,则返回一个新的排序后的对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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()

#按列索引标签降序排序
df_sorted = df.sort_index(axis=1,ascending=False)
print(df_sorted)

结果:

1
2
3
4
C  B  A
b 7 4 1
c 8 5 2
a 9 6 3

2.2 sort_values

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

1
2
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。

1
2
3
4
5
6
7
8
9
10
11
import pandas as pd
data = {
'name': ['Charlie', 'Bob', 'Alice','Alice'],
'age': [40, 30, 20,31],
'score': [85, 90, 88, 60]
}
df = pd.DataFrame(data)

# 里面如果有重复的,按照第二个排序即age升序排列,只排序一列不用加[]
f = df.sort_values(by=['name','age'], ascending=[True, True])
print(f)

结果:

1
2
3
4
5
name  age  score
2 Alice 20 88
3 Alice 31 60
1 Bob 30 90
0 Charlie 40 85

三.去重

drop_duplicates 方法用于删除 DataFrame 或 Series 中的重复行或元素。

1
2
drop_duplicates
(by=None, subset=None, keep='first', inplace=False)

参数:

  • subset:与 by 类似,但用于指定列的子集。

  • keep :指定如何处理重复项。可以是:

  • first :保留第一个出现的重复项(默认值)。

  • last :保留最后一个出现的重复项。

  • False :删除所有重复项。

  • inplace:布尔值,指定是否在原地修改数据。如果为 True,则会修改原始数据;如果为 False,则返回一个新的删除重复项后的对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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)

# 不指定by,使用所有列去重
df.drop_duplicates(inplace=True)
print(df)

# 指定by,使用指定列去重
# 这里传谁进去都一样,因为例子里都是同两行的位置重复,所以删除的也只可能是那两行
df.drop_duplicates(subset = ['A'], inplace=True)
print(df)

结果:

1
2
3
4
5
6
7
8
A  B  C
0 1 4 7
1 2 5 8
3 3 6 9
A B C
0 1 4 7
1 2 5 8
3 3 6 9
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import pandas as pd

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

# keep保留最后一个重复项
f1 = df1.drop_duplicates(subset=['A'], keep='last',inplace=False)
print(f1)

# keep=False,删除所有重复项
f2 = df1.drop_duplicates(subset=['A'], keep=False,inplace=False)
print(f2)

结果:

1
2
3
4
5
6
7
A  B  C
0 1 4 7
2 2 5 8
3 3 6 9
A B C
0 1 4 7
3 3 6 9

四.分组

将数据集按照某个列(或多个列)的值分组,期间一列或一行相同的值归为一组。

1
2
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。

1
2
3
4
5
6
7
8
9
10
11
12
import pandas as pd
data = {
'name': ['Charlie', 'Bob', 'Alice','Alice'],
'age': [40, 30, 20,31],
'score': [85, 90, 88, 60]
}
df = pd.DataFrame(data)

# 按name列分,这里返回一个分组对象
s = df.groupby('name')
# 转换成列表方便观察
print(list(s))

结果:

1
2
3
4
5
[('Alice',     name  age  score
2 Alice 20 88
3 Alice 31 60), ('Bob', name age score
1 Bob 30 90), ('Charlie', name age score
0 Charlie 40 85)]
1
2
3
4
5
6
7
# 用分组后对象计算相关数据,这里是使用分组后的每个组里的score来计算
scoreall = s['score'].mean()
print(scoreall)

# 计算分组后其他所有列的平均值
Ds = df.groupby('name').mean()
print(Ds)

结果:

1
2
3
4
5
6
7
8
9
10
name
Alice 74.0
Bob 90.0
Charlie 85.0
Name: score, dtype: float64
age score
name
Alice 25.5 74.0
Bob 30.0 90.0
Charlie 40.0 85.0

用transform把计算后的数据添加到原来的DataFrame中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import pandas as pd
data = {
'name': ['Charlie', 'Bob', 'Alice','Alice'],
'age': [40, 30, 20,31],
'score': [85, 90, 88, 60]
}
df = pd.DataFrame(data)

# 按name列分,这里返回一个分组对象
s = df.groupby('name')

# 使用transform方法计算每个分组的均值,返回一个series,其name是原始dataframe的列名
x = s['score'].transform('mean')
df['S-mean()'] = x
print(df)

结果:

1
2
3
4
5
6
7
8
9
10
11
0    85.0
1 90.0
2 74.0
3 74.0
Name: score, dtype: float64
name age score S-mean()
0 Charlie 40 85 85.0
1 Bob 30 90 90.0
2 Alice 20 88 74.0
3 Alice 31 60 74.0
————————————————

4.2 filter

根据定义的条件过滤数据并返回一个新的数据集。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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' 的平均值大于 5 的组
filtered = df.groupby('A').filter(lambda x: x['C'].mean() >= 5)

print(filtered)

结果:

1
2
3
Empty DataFrame
Columns: [A, B, C, D]
Index: []