分类聚合
实例1:根据A列相同行合并B列的值
import pandas as pd
# 创建示例DataFrame
data = {'A': [1, 1, 2, 2, 3],
'B': ['apple', 'banana', 'cherry', 'date', 'elderberry'],
'C': [10, 20, 30, 40, 50],
'D': [50, 40, 30, 20, 10]}
df = pd.DataFrame(data)
df
0 |
1 |
apple |
10 |
50 |
1 |
1 |
banana |
20 |
40 |
2 |
2 |
cherry |
30 |
30 |
3 |
2 |
date |
40 |
20 |
4 |
3 |
elderberry |
50 |
10 |
使用groupby和agg方法将列B内容合并
df_merged = df.groupby('A').agg({'B': ', '.join}).reset_index()
df_merged
0 |
1 |
apple, banana |
1 |
2 |
cherry, date |
2 |
3 |
elderberry |
说明:这种写法df.groupby('A').agg({'B': ', '.join})
,聚合函数,如', '.join
的参数是按A列分组后B列的各个值,如[apple, banana]
,其类型是Series,返回的结果是DataFrame。
使用groupby和agg方法将列B内容合并并保留列C第一行
df_merged = df.groupby('A').agg({'B': ', '.join, 'C': 'first'}).reset_index() # 保留C列的第一行
df_merged
0 |
1 |
apple, banana |
10 |
1 |
2 |
cherry, date |
30 |
2 |
3 |
elderberry |
50 |
使用groupby和agg方法将列B内容合并并保留所有其他列第一行
df_merged = df.groupby('A').agg(lambda x: ', '.join(x) if x.name=='B' else x.iloc[0]).reset_index()
df_merged
0 |
1 |
apple, banana |
10 |
50 |
1 |
2 |
cherry, date |
30 |
30 |
2 |
3 |
elderberry |
50 |
10 |
实例2:按A列分组,判断每组B列是否全部为空
# 创建示例数据框
data = {
'A': ['group1', 'group1', 'group2', 'group2', 'group3'],
'B': [1, None, None, None, None]
}
df = pd.DataFrame(data)
df
0 |
group1 |
1.0 |
1 |
group1 |
NaN |
2 |
group2 |
NaN |
3 |
group2 |
NaN |
4 |
group3 |
NaN |
# 写法1
result1 = df.groupby('A')['B'].apply(lambda x: x.isna().all())
result1
A
group1 False
group2 True
group3 True
Name: B, dtype: bool
说明:这种写法df.groupby('A')['B'].apply(lambda x: x.isna().all())
,聚合函数,如lambda x: x.isna().all()
的参数是按A列分组后B列的各个值,如[1.0, NaN]
,其类型是Series,返回的是Series。
# 写法2
result2 = df.groupby('A').agg({'B': lambda x: x.isna().all()})
result2
A |
|
group1 |
False |
group2 |
True |
group3 |
True |
实例3:按A列分组,每组B列双向填充空值
data = {
'A': ['group1', 'group1', 'group2', 'group2', 'group2', 'group3', 'group3'],
'B': [1, None, None, 2, None, None, 5],
'C': ['长嘱', '长嘱','长嘱','长嘱','长嘱','临嘱','临嘱',]
}
df = pd.DataFrame(data)
df
0 |
group1 |
1.0 |
长嘱 |
1 |
group1 |
NaN |
长嘱 |
2 |
group2 |
NaN |
长嘱 |
3 |
group2 |
2.0 |
长嘱 |
4 |
group2 |
NaN |
长嘱 |
5 |
group3 |
NaN |
临嘱 |
6 |
group3 |
5.0 |
临嘱 |
df1 = df.copy()
df1.B = df.groupby('A', group_keys = False)['B'].apply(
lambda x : x.ffill().bfill()
)
df1
0 |
group1 |
1.0 |
长嘱 |
1 |
group1 |
1.0 |
长嘱 |
2 |
group2 |
2.0 |
长嘱 |
3 |
group2 |
2.0 |
长嘱 |
4 |
group2 |
2.0 |
长嘱 |
5 |
group3 |
5.0 |
临嘱 |
6 |
group3 |
5.0 |
临嘱 |
df2 = df.copy()
mask = df.C == '长嘱'
df2.loc[mask, 'B'] = df[mask].groupby('A', group_keys = False)['B'].apply(
lambda x : x.ffill().bfill()
)
df2
0 |
group1 |
1.0 |
长嘱 |
1 |
group1 |
1.0 |
长嘱 |
2 |
group2 |
2.0 |
长嘱 |
3 |
group2 |
2.0 |
长嘱 |
4 |
group2 |
2.0 |
长嘱 |
5 |
group3 |
NaN |
临嘱 |
6 |
group3 |
5.0 |
临嘱 |
#### 实例4 对载入包集合去重
import re
def deduplicate_import_set(import_set: set):
'''
import re
import pandas as pd
'''
df = pd.DataFrame([re.split(r"(?<=[@|])", package) for package in import_set], columns = ['package', 'alias_or_subpackage'])
# 填充空值为空字符串,后面处理的对象要求是字符串
df.alias_or_subpackage = df.alias_or_subpackage.fillna('')
# 分组聚合
## 聚合的结果要求是同组的alias_or_subpackage得到并集,防止重复导入
### 第一步:"+".join(x)将同一组的subpackage通过+连接成一个字符串
### 第二步: "+".join(x).split('+')再次将字符串分割成列表
### 第三步: set("+".join(x).split('+'))去除列表中的重复元素
### 第四步:"+".join(set("+".join(x).split('+')))再次将字符还原成原来通过+相连接的格式
df = df.groupby('package').agg({'alias_or_subpackage': lambda x : "+".join(set("+".join(x).split('+')))}).reset_index()
# 还原成import_set
import_set = {f"{package}{alias_or_subpackage}" for package, alias_or_subpackage in df.values.tolist()}
return import_set
import_set = {'flask|request', 'feffery_antd_components@fac', 'dash.dependencies|Output+Input+State', 'matplotlib.pyplot@plt', 'dash.dependencies|Output+Input', 'dash', 'shutil', 'uuid|uuid4', 'pandas@pd', 'os', 'dash|dcc+html'}
import_set_deduplicated = deduplicate_import_set(import_set)
import_set_deduplicated
{'dash',
'dash.dependencies|Input+Output+State',
'dash|dcc+html',
'feffery_antd_components@fac',
'flask|request',
'matplotlib.pyplot@plt',
'os',
'pandas@pd',
'shutil',
'uuid|uuid4'}
分组筛选
实例1:按A列分组,筛选每组B列全部为空的行
df_colb_isna_all = (
df
.groupby('A')
.filter(lambda group : group['B'].isna().all())
)
df_colb_isna_all