如何高效为Pandas DataFrame非空单元格添加递增数字前缀?
高效实现为DataFrame非空单元格添加递增前缀并收集文本
需求说明
从CSV导入的Pandas DataFrame包含空单元格,需完成以下操作:
- 为所有非空单元格添加递增数字前缀,结果存入对应新列(如原列
x对应pre-x) - 将所有非空单元格的文本收集到
out列表,数字递增顺序需与out列表的元素顺序一致
现有循环实现可得到正确结果,但需更高效的向量化方案,曾尝试np.where()但无法实现计数递增。
初始循环实现
import pandas as pd df = pd.DataFrame( [[ "", "c", "e"], ["a", "", ""], ["b", "d", "f"]], columns = ["x", "y", "z"] ) count = 1 out = [] # 遍历每一列 for col in df.columns: tmp = [] # 遍历列内每个元素,非空则添加前缀 for text in df[col]: if text: tmp.append(str(count) + "-" + text) out.append(text) count += 1 else: tmp.append("") # 添加带前缀的新列 df["pre-" + col] = tmp
优化向量化实现
利用Pandas的向量化操作替代嵌套循环,大幅提升处理效率,同时支持数字格式化(如补零至4位):
import pandas as pd import numpy as np df = pd.DataFrame( [[ "", "c", "e"], ["a", "", ""], ["b", "d", "f"]], columns = ["x", "y", "z"] ) # 替换空字符串为NaN,便于堆叠过滤非空值 s = df.replace('', np.nan).T.stack() # 生成带格式化前缀的序列,再重构为原结构的DataFrame prefixed_df = (s.notna().cumsum().apply(lambda x: f"{x:04}-") + s).unstack().T.fillna('') # 拼接原DataFrame与带前缀的新列 df = df.join(prefixed_df.add_prefix("pre-")) # 收集所有非空文本到out列表 out = s.tolist()
关键步骤说明
- 空值替换与堆叠:将空字符串转为NaN后,通过
T.stack()提取所有非空单元格,形成一维序列 - 递增计数与前缀格式化:用
cumsum()生成全局递增的计数,结合lambda函数实现数字补零格式化(如0001-、0002-) - 重构与拼接:通过
unstack().T将序列还原为原DataFrame结构,空值填充为空字符串后与原表拼接 - 文本列表收集:直接从堆叠后的序列
s提取所有非空文本,顺序与数字前缀完全一致
内容的提问来源于stack exchange,提问作者Dredd
相关产品推荐
相关产品推荐

