基于城市与区域列的Pandas DataFrame特定条件聚合计算问询
没问题!这在Pandas里完全能实现,我来一步步给你拆解操作方法:
步骤1:筛选出同时包含Buy和Sell的City-Zone组合
首先得先把那些既有买入又有卖出记录的(City, Zone)组挑出来,毕竟我们只需要对这类组合做后续计算。这里有两种简洁的实现方式:
方法一:先找出有效组合再筛选
# 假设你的DataFrame叫df,交易类型列是'Type' # 统计每个(City, Zone)组里的交易类型种类数,筛选出至少包含2种的组 valid_groups = df.groupby(['City', 'Zone'])['Type'].nunique() >= 2 # 获取符合条件的(City, Zone)组合 valid_pairs = valid_groups[valid_groups].index # 从原DataFrame里筛选出这些组合的记录 filtered_df = df[df.set_index(['City', 'Zone']).index.isin(valid_pairs)]
方法二:用transform标记有效行
# 给每行标记所在组是否同时有Buy和Sell df['has_both_types'] = df.groupby(['City', 'Zone'])['Type'].transform(lambda x: x.nunique() >= 2) # 筛选出有效行并去掉标记列 filtered_df = df[df['has_both_types']].drop('has_both_types', axis=1)
步骤2:根据买卖记录数量执行聚合计算
接下来针对这些有效组,就可以按照你说的规则来处理了。比如你提到“若卖出记录多于买入,仅保留……”,我举两个常见的场景示例,你可以根据自己的实际需求调整:
示例1:保留数量较多的交易类型的所有记录
比如卖出多就留所有卖出记录,买入多就留所有买入记录,数量相等时可以选择保留全部:
def process_group(group): buy_count = (group['Type'] == 'Buy').sum() sell_count = (group['Type'] == 'Sell').sum() if sell_count > buy_count: return group[group['Type'] == 'Sell'] elif buy_count > sell_count: return group[group['Type'] == 'Buy'] else: # 数量相等时的自定义处理,这里选择保留全部记录 return group # 对每个有效组应用处理函数,最后重置索引 result = filtered_df.groupby(['City', 'Zone']).apply(process_group).reset_index(drop=True)
示例2:计算每组的净交易量(以金额为例)
如果你的数据有金额列(比如叫'Amount'),可以计算每组的净金额(比如买入为正,卖出为负,求和得到净量):
# 先给交易类型标记正负值,根据你的数据逻辑调整正负 df['signed_amount'] = df.apply(lambda row: row['Amount'] if row['Type'] == 'Buy' else -row['Amount'], axis=1) # 对有效组计算净金额 net_result = filtered_df.groupby(['City', 'Zone'])['signed_amount'].sum().reset_index(name='net_amount')
验证效果
就像你说的例子,Cardiff Zone 2因为只有一条记录,会被第一步的筛选排除;而Cardiff Zone 1和Bristol Zone 1会被保留,然后按照你设定的规则完成聚合。
内容的提问来源于stack exchange,提问作者JRH31
相关产品推荐
相关产品推荐

