按地理坐标筛选区域内门店销售额求和问题求助
计算门店覆盖区域内的销售额总和问题
问题背景
需要根据门店的地理坐标,为每一行数据计算所有坐标落在该行门店覆盖区域内的门店销售额总和。其中X、Y为门店坐标,X_MIN、Y_MIN、X_MAX、Y_MAX为门店覆盖区域的边界。
样本数据
data={'ID':['1','2','3','4'],'SALE':[100,120,110,95],'X':[23,22,21,24],'Y':[44,45,41,46],'X_MIN':[22,21,20,23],'Y_MIN':[43,44,40,45],'X_MAX':[24,23,22,25],'Y_MAX':[45,46,42,47]}
| ID | SALE | X | Y | X_MIN | Y_MIN | X_MAX | Y_MAX |
|---|---|---|---|---|---|---|---|
| 1 | 100 | 23 | 44 | 22 | 43 | 24 | 45 |
| 2 | 120 | 22 | 45 | 21 | 44 | 23 | 46 |
| 3 | 110 | 21 | 41 | 20 | 40 | 22 | 42 |
| 4 | 95 | 24 | 46 | 23 | 45 | 25 | 47 |
预期结果
final={'ID':['1','2','3','4'],'SUM':[220,220,110,95]}
| ID | SUM |
|---|---|
| 1 | 220 |
| 2 | 220 |
| 3 | 110 |
| 4 | 95 |
尝试的代码及报错
尝试的代码:
data['SUM'] = data.apply(lambda x: data['SALE'].sum(data[(data['X'] >= x['X_MIN'])&(data['X'] <= x['X_MAX'])&(data['Y'] >= x['Y_MIN'])&(data['Y'] <= x['Y_MAX'])]),axis=1)
报错信息:
TypeError: unhashable type: 'DataFrame'
问题分析与解决方法
错误原因
data['SALE'].sum()方法不需要传入DataFrame参数,你错误地将筛选后的DataFrame传递给了sum(),导致类型不匹配的错误。正确逻辑是先筛选符合条件的行,再对这些行的SALE列求和。
修正后的基础代码
import pandas as pd # 转换字典为DataFrame df = pd.DataFrame(data) # 逐行计算覆盖区域内销售额总和 df['SUM'] = df.apply(lambda row: df.loc[ (df['X'] >= row['X_MIN']) & (df['X'] <= row['X_MAX']) & (df['Y'] >= row['Y_MIN']) & (df['Y'] <= row['Y_MAX']), 'SALE' ].sum(), axis=1) # 输出结果 print(df[['ID', 'SUM']])
代码说明
- 先将原始字典转为pandas DataFrame,便于数据操作。
- 使用
apply逐行处理:- 针对每一行的覆盖区域边界,筛选出所有坐标落在该区域内的门店。
- 提取这些门店的
SALE列并求和,赋值给当前行的SUM字段。
- 最后提取
ID和SUM列,得到预期结果。
高效优化方案(适合大数据集)
如果数据量较大,逐行apply的效率偏低,可以利用numpy广播机制一次性计算所有条件:
import pandas as pd df = pd.DataFrame(data) # 生成布尔矩阵,判断每个门店是否在其他门店的覆盖区域内 mask = ( (df['X'].values[:, None] >= df['X_MIN'].values) & (df['X'].values[:, None] <= df['X_MAX'].values) & (df['Y'].values[:, None] >= df['Y_MIN'].values) & (df['Y'].values[:, None] <= df['Y_MAX'].values) ) # 矩阵乘法计算每个区域的销售额总和 df['SUM'] = mask @ df['SALE'].values print(df[['ID', 'SUM']])
这种方法避免了循环,通过向量运算提升处理效率,适合大规模数据场景。
内容的提问来源于stack exchange,提问作者Patryk Kołakowski
相关产品推荐
相关产品推荐

