看过来
《pandas 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gairuo123(备注:pandas教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
本需求为一组订单数据,一个订单有两条数据,一个为订单使用的优惠类型及优惠金额,另外一个为该优惠的补贴金额。由于补贴数据类型全部标记为「补贴」,这了方便我们查看,需要根据同订单的优惠类型,将补贴全部替换为优惠类型-补贴的形式。
以下为数据,我们先读入 DataFrame 数据对象:
import pandas as pd
from io import StringIO
data = '''
类型,订单,金额
补贴,1001,5
会员卡,1001,10
补贴,1002,8
优惠券,1002,19
补贴,1003,9
第三方,1003,20
补贴,1004,5
会员卡,1004,10
'''
df = pd.read_csv(StringIO(data))
df
# ...
根据需求,比如第一行数据的类型名为补贴,按订单号 1001 对应的类型列非补贴值修改为「会员卡-补贴」,其他订单类型。
这里我们假定优惠类型和补贴前后相对位置不固定。
由于是按订单进行操作,我们要按订单分组,分组后只操作类型列,我们应用一个函数来操作,接下来就是考虑怎么操作个这个分组后的 Series。
我们来思考下每个订单的类型列组成的 Series 如何处理。我们要做的就是将值不为「补贴」的替换为「其他值-补贴」的形式。
我们接下来就是按这个思路编写代码。
先来编写分组处理函数。由于为「补贴」的要替换,我们用 mask() 圈选出来操作:
def func(grouped: pd.Series):
# 对非补贴值的内容拼接「-补贴」
foo = grouped.loc[lambda s: ~(s=='补贴')].squeeze()+'-补贴'
# 对值是「补贴」的内容进行替换
return grouped.mask(grouped=='补贴', foo)
以上代码中 squeeze() 可以将我们筛选出的长度为 1 的 Series 转为标量。
最后,应该通过分组应用这个函数:
# 对类型列进行替换,按订单号分组后对分组内的类型列应用函数
df.assign(类型=df.groupby('订单').类型.apply(func))
'''
类型 订单 金额
0 会员卡-补贴 1001 5
1 会员卡 1001 10
2 优惠券-补贴 1002 8
3 优惠券 1002 19
4 第三方-补贴 1003 9
5 第三方 1003 20
6 会员卡-补贴 1004 5
7 会员卡 1004 10
'''
这样我们就完成了需求。
(完)
更新时间:2024-08-18 15:56:54 标签:pandas python 修改