Pandas:多DataFrame含不等长列表转置合并,保留NaN
嘿,我来帮你解决这个问题!你遇到的NaN被跳过的问题,根源在于处理Locations列时调用了dropna(),把包含NaN的行直接删掉了,自然合并的时候就看不到这些组合啦。下面给你两种解决方案,选你顺手的来用:
方法一:用explode一步到位(最简洁)
Pandas的explode方法专门用来把列表拆成多行,而且从版本1.3.0开始支持dropna参数,刚好可以保留NaN。我们只需要对每一列依次执行explode,最后重命名列名就搞定了:
import pandas as pd # 假设你的原始DataFrame是df df_final = df.explode('Job positions') \ .explode('Job types') \ .explode('Locations', dropna=False) # 重命名列名到你想要的格式 df_final = df_final.rename(columns={ 'Job positions': 'Job position', 'Job types': 'Job type', 'Locations': 'Location' }) # 查看结果 print(df_final)
这样执行后,就会得到你期望的所有组合,包括包含NaN的行。
方法二:修正你原来的melt+reduce方法
如果你更习惯用自己原来的思路,只需要修改Locations列的处理逻辑,去掉dropna(),同时给每个列的value重命名,避免合并后列名冲突:
import pandas as pd from functools import reduce # 处理Job positions列,保留index和拆分后的值 positions = df['Job positions'].apply(pd.Series).reset_index() \ .melt(id_vars='index').dropna()[['index', 'value']] \ .set_index('index').rename(columns={'value': 'Job position'}) # 处理Job types列,同样保留index和拆分后的值 types = df['Job types'].apply(pd.Series).reset_index() \ .melt(id_vars='index').dropna()[['index', 'value']] \ .set_index('index').rename(columns={'value': 'Job type'}) # 处理Locations列,关键:不要调用dropna(),保留NaN locations = df['Locations'].apply(pd.Series).reset_index() \ .melt(id_vars='index')[['index', 'value']] \ .set_index('index').rename(columns={'value': 'Location'}) # 合并三个DataFrame,按index做笛卡尔积合并 dfs = [positions, types, locations] df_final = reduce(lambda left, right: pd.merge(left, right, left_index=True, right_index=True, how='outer'), dfs) # 查看结果 print(df_final)
这里的核心就是不要对Locations列执行dropna(),这样原始数据里的NaN就会被保留下来,合并时就能生成对应的组合了。
内容的提问来源于stack exchange,提问作者Mathias Lund
相关产品推荐
相关产品推荐

