遍历DataFrame行时快速检查条件并新增列的方法
解决方案:为DataFrame按SHOP新增条件检查列
先把你的原始数据整理成清晰的Markdown表格:
| START | END | SHOP | ACTION |
|---|---|---|---|
| 2016-01-07 | 2016-01-10 | ABC | B |
| 2016-01-10 | 2016-02-07 | ABC | B |
| 2016-04-07 | 2016-05-07 | ABC | B |
| 2016-05-15 | 2016-05-18 | ABC | S |
| 2016-10-07 | 2016-10-07 | ABC | B |
| 2016-11-07 | 2016-11-07 | ABC | B |
| 2016-01-15 | 2016-01-22 | DEF | S |
| 2016-05-22 | 2016-11-07 | DEF | S |
| 2016-11-07 | 2016-12-07 | DEF | S |
| 2016-01-04 | 2016-02-04 | XYZ | B |
| 2016-09-07 | 2016-10-26 | XYZ | T |
| 2016-10-25 | 2016-10-30 | XYZ | B |
我会以检查每个SHOP是否存在至少一条ACTION为'S'的记录为例,展示新增列的实现方法,你可以根据实际需求修改条件逻辑。
实现代码
import pandas as pd # 构造你的原始DataFrame data = { 'START': ['2016-01-07', '2016-01-10', '2016-04-07', '2016-05-15', '2016-10-07', '2016-11-07', '2016-01-15', '2016-05-22', '2016-11-07', '2016-01-04', '2016-09-07', '2016-10-25'], 'END': ['2016-01-10', '2016-02-07', '2016-05-07', '2016-05-18', '2016-10-07', '2016-11-07', '2016-01-22', '2016-11-07', '2016-12-07', '2016-02-04', '2016-10-26', '2016-10-30'], 'SHOP': ['ABC', 'ABC', 'ABC', 'ABC', 'ABC', 'ABC', 'DEF', 'DEF', 'DEF', 'XYZ', 'XYZ', 'XYZ'], 'ACTION': ['B', 'B', 'B', 'S', 'B', 'B', 'S', 'S', 'S', 'B', 'T', 'B'] } df = pd.DataFrame(data) # 新增列:检查每个SHOP是否存在ACTION='S'的记录 df['HAS_S_ACTION'] = df.groupby('SHOP')['ACTION'].transform(lambda x: any(x == 'S')) print(df)
代码逻辑说明
groupby('SHOP'):按店铺分组,把同一个SHOP的所有记录归为一组,方便单独检查每个店铺的条件。transform(lambda x: any(x == 'S')):对每个分组的ACTION列执行检查——只要分组里有任意一个值是'S',就返回True,否则返回False。transform会把结果同步到原DataFrame的每一行,保证同一个店铺的所有行都有相同的检查结果。
最终输出结果
运行代码后,你的DataFrame会新增HAS_S_ACTION列,结果如下:
| START | END | SHOP | ACTION | HAS_S_ACTION |
|---|---|---|---|---|
| 2016-01-07 | 2016-01-10 | ABC | B | True |
| 2016-01-10 | 2016-02-07 | ABC | B | True |
| 2016-04-07 | 2016-05-07 | ABC | B | True |
| 2016-05-15 | 2016-05-18 | ABC | S | True |
| 2016-10-07 | 2016-10-07 | ABC | B | True |
| 2016-11-07 | 2016-11-07 | ABC | B | True |
| 2016-01-15 | 2016-01-22 | DEF | S | True |
| 2016-05-22 | 2016-11-07 | DEF | S | True |
| 2016-11-07 | 2016-12-07 | DEF | S | True |
| 2016-01-04 | 2016-02-04 | XYZ | B | False |
| 2016-09-07 | 2016-10-26 | XYZ | T | False |
| 2016-10-25 | 2016-10-30 | XYZ | B | False |
自定义条件修改
如果你的实际需求不是检查'S',可以直接修改transform里的lambda逻辑:
- 检查每个SHOP是否有ACTION='T':把
any(x == 'S')改成any(x == 'T') - 检查每个SHOP是否有连续的'B'记录:可以用
any(x.shift() == x)判断相邻值是否相同 - 检查时间范围是否重叠:可以在分组里对START和END列做时间区间判断
内容的提问来源于stack exchange,提问作者asimo
相关产品推荐
相关产品推荐

