解决Pandas中按动态条件统计符合要求行数的循环卡顿问题
问题描述
现有店铺坐标数据如下:
data={'ID':['1','2','3','4'],'X':[23,22,21,24],'Y':[44,45,41,46],'X_MIN':[22,21,20,23],'Y_MIN':[43,44,40,45]}
对应表格:
| ID | X | Y | X_MIN | Y_MIN |
|---|---|---|---|---|
| 1 | 23 | 44 | 22 | 43 |
| 2 | 22 | 45 | 21 | 44 |
| 3 | 21 | 41 | 20 | 40 |
| 4 | 24 | 46 | 23 | 45 |
需求:为每个店铺,用其自身的X_MIN和Y_MIN作为条件,统计所有满足X >= X_MIN且Y >= Y_MIN的店铺数量,期望结果:
final={'ID':['1','2','3','4'],'count':[3,3,4,1]}
对应表格:
| ID | count |
|---|---|
| 1 | 3 |
| 2 | 3 |
| 3 | 4 |
| 4 | 1 |
用户尝试用Pandas循环实现,但代码逻辑错误,代码如下:
test=df calc=[] for i, row in df.iterrows(): test['X_MIN']=row['X_MIN'] test['Y_MIN']=row['Y_MIN'] count=test[['X','Y','X_MIN','Y_MIN']].query('X>=X_MIN and Y>=Y_MIN') a=count['X'].count() calc.append(a)
错误原因
test = df是引用赋值,修改test的列会直接覆盖原df的X_MIN和Y_MIN,导致后续循环的条件完全错误。- 每次循环将所有行的
X_MIN/Y_MIN替换为当前行的值,相当于所有店铺都用同一个条件判断,而非用每个店铺的原始条件匹配全量数据。
解决方案
方案1:修复循环逻辑
不修改原数据,每次用当前行的条件匹配原数据的所有行:
import pandas as pd data={'ID':['1','2','3','4'],'X':[23,22,21,24],'Y':[44,45,41,46],'X_MIN':[22,21,20,23],'Y_MIN':[43,44,40,45]} df = pd.DataFrame(data) calc = [] for _, row in df.iterrows(): # 用当前行的条件筛选原数据中符合要求的行 mask = (df['X'] >= row['X_MIN']) & (df['Y'] >= row['Y_MIN']) count = mask.sum() # 布尔值求和,True=1、False=0 calc.append(count) # 生成结果表 final_df = pd.DataFrame({'ID': df['ID'], 'count': calc}) print(final_df)
输出符合预期:
ID count 0 1 3 1 2 3 2 3 4 3 4 1
方案2:向量化操作(高效推荐)
利用Pandas广播机制批量判断,避免循环,数据量越大效率优势越明显:
import pandas as pd data={'ID':['1','2','3','4'],'X':[23,22,21,24],'Y':[44,45,41,46],'X_MIN':[22,21,20,23],'Y_MIN':[43,44,40,45]} df = pd.DataFrame(data) # 广播运算生成布尔矩阵,判断每个店铺的X/Y是否满足其他店铺的X_MIN/Y_MIN x_mask = df['X'].values[:, None] >= df['X_MIN'].values y_mask = df['Y'].values[:, None] >= df['Y_MIN'].values # 两个条件同时满足,每行求和得到对应店铺的计数 counts = (x_mask & y_mask).sum(axis=0) # 生成结果表 final_df = pd.DataFrame({'ID': df['ID'], 'count': counts}) print(final_df)
内容的提问来源于stack exchange,提问作者Patryk Kołakowski
相关产品推荐
相关产品推荐

