基于全NaN行拆分Pandas DataFrame时单列NaN导致逻辑失效及额外NaN行问题的解决方案咨询
我来帮你搞定这个问题!先拆解下你遇到的两个核心问题:
- 你用
dropna()的时候,会把所有包含NaN的行(哪怕只有单个列是NaN)都删掉,导致原本要保留的行(比如那行value为NaN的B类型数据)直接丢失了; - 分组后最后会多出一个全NaN的空组,合并后就多了一行多余的空行。
下面是修正后的完整方案,我会一步步解释:
问题根源&修正思路
- 你的
grps = dfs.isnull().all(axis=1).cumsum()这个分组逻辑是对的——它只会把全NaN的行作为分隔符来分组,没问题; - 错就错在后面的
dropna(),应该改成只过滤全NaN的行,保留那些部分列有NaN的有效数据; - 另外要过滤掉分组后产生的空组,避免最后多出空行;
- 最后建议用
pd.concat替代已经被弃用的append,更符合pandas的最新规范。
修正后的完整代码
import pandas as pd from pprint import pprint import numpy as np d = { 't': [0, 1, 2, 0, 2, 0, 1], 'input': [2, 2, 2, 2, 2, 2, 4], 'type': ['A', 'A', 'A', 'B', 'B', 'B', 'A'], 'value': [0.1, 0.2, 0.3, np.nan, 2, 3, 1], } df = pd.DataFrame(d) # 按t的递减分割原始DataFrame,并添加全NaN分隔行(这里微调了分隔行的生成方式,确保列名一致) dup = df['t'].diff().lt(0).cumsum() dfs = ( df.groupby(dup, as_index=False, group_keys=False) .apply(lambda x: pd.concat([x, pd.DataFrame([[np.nan]*len(x.columns)], columns=x.columns)])) ) pprint(dfs) # 生成分组标识:全NaN行作为分隔,累计计数(这部分逻辑保留,是对的) grps = dfs.isnull().all(axis=1).cumsum() # 分组处理:过滤每个组里的全NaN行,同时跳过空组 temp = [] for _, group in dfs.groupby(grps): # 只保留非全NaN的行,保留部分列有NaN的有效数据 valid_rows = group[~group.isnull().all(axis=1)] # 跳过空组,避免最后多出空行 if not valid_rows.empty: temp.append(valid_rows) # 为每个子DataFrame添加name列,合并时加上分隔行 dfm_parts = [] for idx, sub_df in enumerate(temp): sub_df['name'] = f'name{idx}' # 添加全NaN分隔行 separator = pd.DataFrame([[np.nan]*len(sub_df.columns)], columns=sub_df.columns) dfm_parts.append(pd.concat([sub_df, separator], ignore_index=True)) # 合并所有部分得到最终结果 dfm = pd.concat(dfm_parts, ignore_index=True) print(dfm)
运行结果
执行后就能得到你想要的输出:
t input type value name 0 0.0 2.0 A 0.1 name0 1 1.0 2.0 A 0.2 name0 2 2.0 2.0 A 0.3 name0 3 NaN NaN NaN NaN NaN 4 0.0 2.0 B NaN name1 5 2.0 2.0 B 2.0 name1 6 NaN NaN NaN NaN NaN 7 0.0 2.0 B 3.0 name2 8 1.0 4.0 A 1.0 name2 9 NaN NaN NaN NaN NaN
内容的提问来源于stack exchange,提问作者Natasha
相关产品推荐
相关产品推荐

