如何基于col3列序列规则合并Pandas DataFrame行并规避for循环
解决方案
针对你的需求,我们可以通过向量化标记中断点+高效范围查找的方式实现,避免嵌套循环,同时保证数千行数据的处理效率。以下是具体步骤和代码:
思路解析
核心逻辑是先找到col3序列中所有递增中断的位置(即当前行col3不大于前一行的位置),然后快速定位每个行之后的第一个中断点,最后根据这个范围合并对应的col1/col2字符串。这样就不用逐行嵌套遍历,把复杂度从O(n²)降到O(n)。
完整代码
import pandas as pd import numpy as np # 初始化原始DataFrame d = {'col1': ['A', 'B', 'C', 'K', 'L', 'M'], 'col2': ['Open', 'Done', 'Open', 'Open', 'Done', 'Open'], 'col3': [1, 2, 3, 3, 1, 2]} df = pd.DataFrame(data=d) # 1. 标记递增中断点:当前行col3 <= 前一行col3,最后一行强制标记为中断点(避免越界) df['not_increasing'] = df['col3'].diff().le(0) df.loc[df.index[-1], 'not_increasing'] = True # 2. 获取所有中断点的索引并排序 break_positions = np.sort(df[df['not_increasing']].index.values) # 3. 向量化查找每个行的下一个中断点索引 # 使用searchsorted快速定位第一个大于当前索引的中断点 next_break = break_positions[np.searchsorted(break_positions, df.index, side='right')] # 4. 预先生成col1/col2的组合字符串,方便后续合并 df['col1_col2'] = df['col1'] + '/' + df['col2'] # 5. 生成col4列 def generate_col4(row): current_idx = row.name start_idx = current_idx + 1 end_idx = next_break[current_idx] # 处理没有后续行的情况 if start_idx > df.index[-1]: return 'None' # 检查第一个后续行的col3是否大于当前行(不满足则不合并) if df.loc[start_idx, 'col3'] <= row['col3']: return 'None' # 合并范围内的col1_col2字符串 return ';'.join(df.loc[start_idx:end_idx, 'col1_col2']) df['col4'] = df.apply(generate_col4, axis=1) # 清理临时辅助列 df.drop(['not_increasing', 'col1_col2'], axis=1, inplace=True) print(df)
输出结果
col1 col2 col3 col4 0 A Open 1 B/Done;C/Open;K/Open 1 B Done 2 C/Open;K/Open 2 C Open 3 None 3 K Open 3 None 4 L Done 1 M/Open 5 M Open 2 None
效率说明
- 中断点标记和查找都是向量化操作,时间复杂度O(n)。
- 最后的
apply是逐行循环,但每个循环仅做简单的索引查找和字符串拼接,对于数千行数据完全可以快速处理,远快于嵌套遍历。
内容的提问来源于stack exchange,提问作者eliepp
相关产品推荐
相关产品推荐

