基于Lev列值生成新列:Pandas DataFrame数据处理需求
问题描述
现有从Excel导入的DataFrame结构如下:
| Lev. | Material | Text | QTY |
|---|---|---|---|
| .1 | X222 | Model3 | 1 |
| .2 | 4027721 | Gruoup1 | 1 |
| .3 | 4647273 | Gruoup1.1 | 4 |
| .3 | 573828 | Gruoup1.2 | 1 |
| .2 | 47883 | Gruoup2 | 1 |
| .3 | 573829 | Gruoup2.1 | 5 |
| .3 | 747458 | Gruoup2.2 | 4 |
需要新增一列NewColumn,规则如下:
- 当
Lev.列值为.1或.2时,取当前行Material列的值 - 当
Lev.为.3时,取NewColumn的上一行值
尝试了以下代码但未得到预期结果:
def categorise_row: if df ["Lev"] == ".1" or ".2" df ["Material"] else df.iloc[-1]["Material"] df ['ColF'] = df.apply (categorise_row)
期望的结果如下:
| Lev. | Material | Text | QTY | NewColumn |
|---|---|---|---|---|
| .1 | X222 | Model3 | 1 | X222 |
| .2 | 4027721 | Gruoup1 | 1 | 4027721 |
| .3 | 4647273 | Gruoup1.1 | 4 | 4027721 |
| .3 | 573828 | Gruoup1.2 | 1 | 4027721 |
| .2 | 47883 | Gruoup2 | 1 | 47883 |
| .3 | 573829 | Gruoup2.1 | 5 | 47883 |
| .3 | 747458 | Gruoup2.2 | 4 | 47883 |
正确实现方法
方法1:利用mask和ffill(推荐,高效简洁)
直接用pandas内置方法实现,性能更优:
import pandas as pd # 假设df是导入后的DataFrame df['NewColumn'] = df['Material'].mask(df['Lev.'] == '.3') df['NewColumn'] = df['NewColumn'].ffill()
原理:
mask(df['Lev.'] == '.3')将Lev.为.3的行的NewColumn设为NaNffill()(向前填充)把NaN替换为上一个非空有效值,完全匹配需求
方法2:自定义函数逐行处理
如果需要逐行逻辑控制,可使用以下代码:
last_val = None def categorise_row(row): global last_val if row['Lev.'] in ['.1', '.2']: last_val = row['Material'] return row['Material'] else: return last_val df['NewColumn'] = df.apply(categorise_row, axis=1)
注意:
- 必须指定
axis=1,让apply按行处理数据 - 用全局变量
last_val跟踪上一行的有效值 - 条件判断用
in ['.1', '.2']实现多值匹配
内容的提问来源于stack exchange,提问作者user19613662
相关产品推荐
相关产品推荐

