Pandas优化咨询:避免行迭代实现租赁交易逐行运算
Pandas优化租赁交易状态追踪方案
数据预处理:拆解结构化字段
首先需要将items列的非结构化列表数据拆分为可计算的结构化字段,这是摆脱循环的核心前提:
import pandas as pd # 假设原始DataFrame名为df # 1. 将items列表拆分为单行单物品记录 df_exploded = df.explode('items') # 2. 从item字符串中提取数量和物品名称 df_exploded[['amount', 'item']] = df_exploded['items'].str.extract(r'(\d+) (.*)') df_exploded['amount'] = df_exploded['amount'].astype(int) # 3. 将date转为可排序的时间类型(如果原始是字符串) df_exploded['date'] = pd.to_datetime(df_exploded['date'])
构建用户物品变化记录
把每笔交易拆分为借出方和借入方的物品变动记录,统一计算逻辑:
# 处理借出方的物品变动:无论借/还,借出方都减少对应数量 df_giver = df_exploded[['date', 'giver', 'item', 'amount']].rename(columns={'giver': 'user'}) df_giver['change'] = -df_giver['amount'] # 处理借入方的物品变动:无论借/还,借入方都增加对应数量 df_taker = df_exploded[['date', 'taker', 'item', 'amount']].rename(columns={'taker': 'user'}) df_taker['change'] = df_taker['amount'] # 合并两方记录并按用户、物品、时间排序(保证交易顺序正确) df_user_items = pd.concat([df_giver, df_taker], ignore_index=True) df_user_items = df_user_items.sort_values(['user', 'item', 'date']).reset_index(drop=True)
计算核心指标
1. 用户物品实时状态字典
通过分组累计求和直接得到每个用户各物品的当前状态,无需循环维护:
# 计算每个用户每个物品的累计数量 df_user_items['current_qty'] = df_user_items.groupby(['user', 'item'])['change'].cumsum() # 转为字典格式:{(user, item): current_qty} user_item_status = df_user_items.groupby(['user', 'item'])['current_qty'].last().to_dict()
2. 每日物品借出量(out字典)
直接筛选loan类型交易,按日期和物品分组求和:
# 按日期+物品统计当日借出总量 out_df = df_exploded[df_exploded['type'] == 'loan'].groupby(['date', 'item'])['amount'].sum().unstack(fill_value=0) # 转为字典:{date: {item: total_amount}} out_dict = out_df.to_dict('index')
3. 用户物品最后一次非零状态交易字典
筛选出状态非零的记录,取每个用户-物品组的最后一条交易日期:
# 筛选所有非零状态的交易记录 non_zero_records = df_user_items[df_user_items['current_qty'] != 0] # 提取每个用户-物品的最后一次非零交易日期 lastzero_dict = non_zero_records.groupby(['user', 'item'])['date'].last().to_dict()
关键优势
- 完全摆脱行迭代,利用Pandas向量化和分组操作提升效率,数据量越大优势越明显
- 所有计算逻辑可追溯,便于调试和维护
- 字典格式的输出完全匹配原需求
内容的提问来源于stack exchange,提问作者Entman
相关产品推荐
相关产品推荐

