如何提取Pandas DataFrame每行首个非零列值?
问题:提取每行首个非零值生成新DataFrame
给定如下结构的Pandas DataFrame:
import pandas as pd data = {"Column1":["0", "1", "0", "0", "1"], "Column2":["2","0","2", "0", "2"], "Column3":["3","0","3", "3", "3"]} df = pd.DataFrame(data) print(df)
输出:
Column1 Column2 Column3 0 0 2 3 1 1 0 0 2 0 2 3 3 0 0 3 4 1 2 3
需要生成新的DataFrame,每行保留原DataFrame中从左到右出现的首个非零值,目标结果如下:
data1 = {"Column1":["2", "1", "2", "3", "1"]} df1 = pd.DataFrame(data1) print(df1)
输出:
Column1 0 2 1 1 2 2 3 3 4 1
尝试使用np.argmax(y, axis=1)未成功,求解决方案。
解决方案
方法一:利用NaN填充提取首个非零值
先将字符串类型的"0"替换为NaN,再通过行方向填充提取首个非空值:
import pandas as pd import numpy as np # 原始数据 data = {"Column1":["0", "1", "0", "0", "1"], "Column2":["2","0","2", "0", "2"], "Column3":["3","0","3", "3", "3"]} df = pd.DataFrame(data) # 将"0"替换为NaN并转换为数值类型 df_numeric = df.replace("0", np.nan).astype(float) # 提取每行第一个非NaN值,生成新DataFrame df1 = df_numeric.bfill(axis=1).iloc[:, 0].to_frame(name="Column1") # 转换为字符串类型匹配目标结果 df1 = df1.astype(int).astype(str) print(df1)
方法二:用stack+分组取首值
通过堆叠列转行,再按原行号分组取第一个非零值:
import pandas as pd import numpy as np df = pd.DataFrame({"Column1":["0", "1", "0", "0", "1"], "Column2":["2","0","2", "0", "2"], "Column3":["3","0","3", "3", "3"]}) # 替换"0"为NaN后堆叠,分组取首值 df1 = df.replace("0", np.nan).stack().groupby(level=0).first().to_frame(name="Column1") # 转换类型 df1 = df1.astype(int).astype(str) print(df1)
方法三:修正np.argmax的用法
原问题中np.argmax失效是因为数据类型和逻辑错误,修正后可以用索引取值:
import pandas as pd import numpy as np df = pd.DataFrame({"Column1":["0", "1", "0", "0", "1"], "Column2":["2","0","2", "0", "2"], "Column3":["3","0","3", "3", "3"]}) # 转换为数值类型 df_num = df.astype(int) # 找到每行第一个非零值的列索引 indices = np.argmax(df_num != 0, axis=1) # 根据索引提取对应值并生成DataFrame result = df_num.values[range(len(df_num)), indices] df1 = pd.DataFrame({"Column1": result.astype(str)}) print(df1)
内容的提问来源于stack exchange,提问作者Elisa
相关产品推荐
相关产品推荐

