Pandas如何按每行Start、Finish列范围计算Data列最大值
问题原因
你之前的代码无法正常运行,核心是三个认知误区:
- 直接在切片里写
'Start'/'Finish'字符串时,pandas会把这两个值当成索引的标签值去匹配切片范围,不会逐行读取这两列的数值作为切片的起止边界,自然得不到正确结果。 - 用
itertools.islice时报错,是因为传入的data2['Start2']/data2['Finish2']是整列的Series对象,而islice要求起止参数必须是单个整数,接收到整列数据时直接触发类型错误。 - 之前试的循环逻辑错误,是因为切片起点固定写死为0,没有读取每行
Start列的数值作为切片起始位置,只会计算从首行到当前行的最大值,不符合需求。
可直接运行的实现代码
方法1:逐行计算(逻辑直观,适合初学者)
逻辑完全匹配你的需求,逐行读取当前行的Start、Finish值做切片,再取区间最大值:
import pandas as pd # 注意修正原代码的拼写错误:读csv用read_csv,文件后缀是csv不是cvs data2 = pd.read_csv('myfile.csv') data2['Finish'] = data2.index # 初始化结果列 data2['new_max_row'] = 0 # 逐行遍历 for idx, row in data2.iterrows(): s = int(row['Start']) e = int(row['Finish']) # 注意Python切片是左闭右开,要包含e位置的元素,结束位置要写e+1 # 用iloc做严格位置切片,避免索引标签和位置混淆出错 data2.loc[idx, 'new_max_row'] = data2['Data'].iloc[s:e+1].max()
运行后结果和你给出的desired_result完全一致,比如索引为7的行,Start=6、Finish=7,切片取索引6、7对应的Data值5和4,最大值为5,符合预期。
方法2:向量化计算(适合万行以上大数据量,性能远高于循环)
如果你的数据量比较大,逐行循环速度慢,可以用numpy做掩码实现向量化计算,速度能提升几十到上百倍:
import numpy as np n = len(data2) data_vals = data2['Data'].values # 构造上三角掩码,只保留行号>=列号的位置(即不超过当前Finish行的范围) mask = np.triu(np.ones((n, n), dtype=bool), k=0) # 再过滤掉列号小于当前行Start值的位置 for i in range(n): mask[i, :int(data2.loc[i, 'Start'])] = False # 把不在区间内的值替换为负无穷,逐行取最大值 broadcast_vals = np.broadcast_to(data_vals, (n, n)).copy() broadcast_vals[~mask] = -np.inf data2['new_max_row'] = broadcast_vals.max(axis=1)
注意事项
- 做基于位置的切片时,优先用
.iloc,直接用[]做切片在索引非默认整数序号时,会优先按索引标签匹配,容易出现非预期结果。 - Python原生切片规则是左闭右开,即
[a:b]会取位置a到b-1的所有元素,要包含结束位置b的元素,切片终点需要写b+1。 - 切片括号内的固定值是字面量,不会自动识别为同名列的逐行值,需要逐行传参时必须显式读取每行对应列的数值,再传入切片参数。
内容的提问来源于stack exchange,提问作者fullspam
相关产品推荐
相关产品推荐

