Python Pandas如何按间隔重复列单元格?数据帧处理求助
问题描述
我有如下DataFrame:
| Code_1 | Code_2 |
|---|---|
| A | C1 |
| B | C2 |
| C | C3 |
| D | C4 |
| E | C5 |
| NaN | C6 |
| NaN | C7 |
| NaN | C8 |
| NaN | C9 |
| NaN | C10 |
我希望每个非NaN的Code_1都对应完整的Code_2序列(C1到C10),尝试了以下代码:
dfa = pd.DataFrame() dfb = pd.DataFrame() dfa['Code_1'] = df['Code_1'] dfb['Code_2'] = df['Code_2'] dfa = dfa.dropna() dfa['times'] = len(dfa) dfa = dfa.loc[dfa.index.repeat(dfa.times)].reset_index(drop=True)
注:df为原始DataFrame
但得到的结果中,后续Code_1对应的Code_2为NaN,我想要的最终效果如下(示例展示A、B部分,完整结果包含C、D、E对应全序列):
| Code_1 | Code_2 |
|---|---|
| A | C1 |
| A | C2 |
| A | C3 |
| A | C4 |
| A | C5 |
| A | C6 |
| A | C7 |
| A | C8 |
| A | C9 |
| A | C10 |
| B | C1 |
| B | C2 |
| B | C3 |
| B | C4 |
| B | C5 |
| B | C6 |
| B | C7 |
| B | C8 |
| B | C9 |
| B | C10 |
请问如何实现Code_2序列随Code_1重复?同时,若有更简便的实现方法也请告知。
解决方案
你需要的是非NaN的Code_1与所有Code_2的笛卡尔积,以下是几种简洁实现方式:
方法1:pandas内置笛卡尔积(最简便)
利用merge的cross参数直接生成笛卡尔积,代码简洁高效:
import pandas as pd # 提取非空的Code_1列 code1_df = df[['Code_1']].dropna().reset_index(drop=True) # 提取所有Code_2列 code2_df = df[['Code_2']].reset_index(drop=True) # 生成笛卡尔积 result = code1_df.merge(code2_df, how='cross')
方法2:用itertools生成组合
借助Python标准库的product生成所有可能的组合,再转为DataFrame:
from itertools import product # 提取非空Code_1列表和所有Code_2列表 code1_list = df['Code_1'].dropna().tolist() code2_list = df['Code_2'].tolist() # 生成所有组合并转为DataFrame combinations = list(product(code1_list, code2_list)) result = pd.DataFrame(combinations, columns=['Code_1', 'Code_2'])
方法3:基于你原思路的调整
如果要沿用你最初的重复索引思路,可修改为:
code1_df = df[['Code_1']].dropna() # 重复每个Code_1,次数等于Code_2的总数 code1_repeated = code1_df.loc[code1_df.index.repeat(len(df))].reset_index(drop=True) # 重复Code_2列表,次数等于非空Code_1的数量 code2_repeated = pd.DataFrame({'Code_2': df['Code_2'].tolist() * len(code1_df)}) # 拼接两部分 result = pd.concat([code1_repeated, code2_repeated], axis=1)
以上三种方法都能得到目标结果,其中**方法1的merge(how='cross')**是pandas推荐的简洁实现,可读性和效率最优。
内容的提问来源于stack exchange,提问作者Naiara Tabanez
相关产品推荐
相关产品推荐

