看过来
《pandas 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gairuo123(备注:pandas教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
本案例的数据为一个分组数据,每个分组内包含几个指标和指标的值,组内最后一个指标为前边所有指标的总体,需求期望将前边的这些指标作为分子,总体作为分母,无需计算只要以字符串的形式显示这个分数即可。同时,前边的指标与这个总体指标也用下划线连接显示。接下来我们用 pandas 来解决这个问题。
我们来构造数据和描述一下需求,数据为:
import pandas as pd
import random
random.seed(7890)
data = {
'A': ['x']*4 + ['y']*4,
'B': [*'abcD']*2,
'C': [random.randint(1,9) for i in range(8)],
}
df = pd.DataFrame(data)
df
'''
A B C
0 x a 4
1 x b 7
2 x c 1
3 x D 7
4 y a 3
5 y b 5
6 y c 2
7 y D 6
'''
A 列为分组,B 列为指标,其中最后一个指标 D 为总体,C 列为指标的值。最终期望生成的新数据如:
'''
A B C
0 x a_D 4/7
1 x b_D 7/7
2 x c_D 1/7
4 y a_D 3/6
5 y b_D 5/6
6 y c_D 2/6
'''
B 列由指标和总体指标(分组最后一个,名称不确定)连接而成,C 列由指标值和总体指标值连接而成。 分组内的总体指标列不需要显示,即没有 D_D
数据。
由于需求是分组需求,我们对数据分组后,每个分组就是一个单独的子 DataFrame,我们定义一个函数来用 apply() 调用,在函数中处理需求逻辑。
在这个处理函数中,我们接受的是一个 DataFrame,B 列和 C 列进行字符拼接,最后再将这些数据生成 DataFrame 返回。
定义分组后单个 DataFrame 数据的处理函数:
def func(grp: pd.DataFrame):
b, c = grp.B, grp.C.astype(str)
b = b.iloc[:-1] + '_' + b.iat[-1]
c = c.iloc[:-1] + '/' + c.iat[-1]
return pd.DataFrame({'A': grp.name, 'B': b, 'C': c})
函数中,以 B 列为例,先选择此列的列包含最后一个数据的所有数据(Series,用 iloc[:-1]
),再选择此列的最后一个值(单个值用 iat[-1]
),然后用 + 法 ( add() 方法)进行拼接。C 列是数字类型,要先转为字符才可拼接。
返回数据的 A 列值 grp.name
中的 name 属性是分组对象子 DataFrame 的分组名,这是分组过程中增加的特有属性。
最终分组调用函数代码:
df.groupby('A', group_keys=False).apply(func)
'''
A B C
0 x a_D 4/7
1 x b_D 7/7
2 x c_D 1/7
4 y a_D 3/6
5 y b_D 5/6
6 y c_D 2/6
'''
代码中 group_keys=False
不保留分组名为索引,保证返回的数据和原数据结构一样。
这样就完成了需求。
(完)
更新时间:2024-08-18 15:55:47 标签:pandas python 分数 分组