如何用Pandas处理不等子集替换DataFrame行数据?
问题描述
现有如下Pandas DataFrame(df1):
| ID | customer_only | city | state |
|---|---|---|---|
| 1 | N | 0 | 0 |
| 1 | Y | 0 | 0 |
| 1 | 0 | A | B |
| 2 | N | 0 | 0 |
| 2 | Y | 0 | 0 |
| 2 | 0 | C | D |
| 2 | 0 | E | F |
| 3 | N | 0 | 0 |
| 3 | Y | 0 | 0 |
| 3 | 0 | G | H |
期望得到的输出为:
| ID | customer_only | city | state |
|---|---|---|---|
| 1 | N | A | B |
| 1 | Y | A | B |
| 2 | N | C | D |
| 2 | N | E | F |
| 2 | Y | C | D |
| 2 | Y | E | F |
| 3 | N | G | H |
| 3 | Y | G | H |
尝试的代码如下:
- 将city和state列的0替换为np.NaN
import pandas as pd import numpy as np data = { "ID": [1,1,1,2,2,2,2,3,3,3], "customer_only": ['N','Y',0,'N','Y',0,0,'N','Y',0], "city": [0,0,'A',0,0,'C','E',0,0,'G'], "state": [0,0,'B',0,0,'D','F',0,0,'H']} df1 = pd.DataFrame(data) df1[['city', 'state']] = df1[['city', 'state']].replace(0, np.NaN)
- 使用bfill()填充缺失值
df1[['city', 'state']] = df1[['city', 'state']].bfill()
但ID=2的情况未达到预期,尝试groupby也无法调整行维度,寻求解决建议。
解决思路与代码
核心需求是:对每个ID,将该ID下customer_only为'N'/'Y'的行,分别与该ID下所有customer_only为0的行(对应有效地址)进行笛卡尔积拼接,同时丢弃原customer_only为0的行。
步骤如下:
- 拆分原始DataFrame为两部分:
- 客户行:筛选
customer_only为'N'或'Y'的行,保留ID和customer_only列 - 地址行:筛选
customer_only为0的行,保留ID、city、state列
- 客户行:筛选
- 按ID对两部分进行内连接,生成每个客户对应所有地址的组合
- 按需排序,得到最终结果
实现代码:
import pandas as pd import numpy as np # 原始数据 data = { "ID": [1,1,1,2,2,2,2,3,3,3], "customer_only": ['N','Y',0,'N','Y',0,0,'N','Y',0], "city": [0,0,'A',0,0,'C','E',0,0,'G'], "state": [0,0,'B',0,0,'D','F',0,0,'H']} df1 = pd.DataFrame(data) # 拆分客户行和地址行 customer_df = df1[df1['customer_only'].isin(['N', 'Y'])][['ID', 'customer_only']] address_df = df1[df1['customer_only'] == 0][['ID', 'city', 'state']] # 按ID内连接,生成笛卡尔积 result = pd.merge(customer_df, address_df, on='ID', how='inner') # 按ID和customer_only排序,匹配预期输出顺序 result = result.sort_values(by=['ID', 'customer_only']).reset_index(drop=True) print(result)
运行后输出:
ID customer_only city state 0 1 N A B 1 1 Y A B 2 2 N C D 3 2 N E F 4 2 Y C D 5 2 Y E F 6 3 N G H 7 3 Y G H
原方法问题分析
之前用bfill()的问题在于:
- 对ID=2,
bfill()只会将第一个有效地址(C,D)填充到前面的NaN行,无法自动复制客户行来匹配多个地址 - 单纯的groupby填充仅能填充缺失值,无法改变行的数量,无法实现"一个客户对应多个地址就生成多行"的需求
内容的提问来源于stack exchange,提问作者SChatcha
相关产品推荐
相关产品推荐

