将pandas DataFrame中的每一行的最后一个非零值转换为0

时间:2019-02-17 21:32:54

标签: python pandas dataframe

我正在尝试以某种方式将数据框修改为将标签编码功能的最后一个变量转换为0。例如,我有此数据框,第一行为标签,第一列为索引:

df
   1  2  3  4  5  6  7  8  9  10
0  0  1  0  0  0  0  0  0  1   1
1  0  0  0  1  0  0  0  0  0   0
2  0  0  0  0  0  0  0  0  1   0

第1-10列是已编码的列。我想要将此数据帧转换为其他内容而不更改任何内容的是:

   1  2  3  4  5  6  7  8  9  10
0  0  1  0  0  0  0  0  0  1   0
1  0  0  0  0  0  0  0  0  0   0
2  0  0  0  0  0  0  0  0  0   0

因此,应将每行中出现的最后一个值转换为0。我当时在考虑使用last_valid_index方法,但这会占用其他剩余的列,并且也会对此进行更改,这是我不希望的。感谢您的帮助

1 个答案:

答案 0 :(得分:1)

您可以使用cumsum来构建布尔掩码,并将其设置为零。

v = df.cumsum(axis=1)
df[v.lt(v.max(axis=1), axis=0)].fillna(0, downcast='infer')

   1  2  3  4  5  6  7  8  9  10
0  0  1  0  0  0  0  0  0  1   0
1  0  0  0  0  0  0  0  0  0   0
2  0  0  0  0  0  0  0  0  0   0

另一个类似的选择是在调用cumsum之前反转,您现在可以在一行中完成此操作。

df[~df.iloc[:, ::-1].cumsum(1).le(1)].fillna(0, downcast='infer')

   1  2  3  4  5  6  7  8  9  10
0  0  1  0  0  0  0  0  0  1   0
1  0  0  0  0  0  0  0  0  0   0
2  0  0  0  0  0  0  0  0  0   0

如果您有更多列,只需将这些操作应用于切片。稍后,分配回来。

u = df.iloc[:, :10]
df[u.columns] = u[~u.iloc[:, ::-1].cumsum(1).le(1)].fillna(0, downcast='infer')