【问题标题】:Convert the last non-zero value to 0 for each row in a pandas DataFrame将 pandas DataFrame 中每一行的最后一个非零值转换为 0
【发布时间】:2019-02-18 06:29:30
【问题描述】:

我正在尝试以将标签编码特征的最后一个变量转换为 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 方法,但这会占用其他剩余的列并改变它,这是我不想要的。任何帮助表示赞赏

【问题讨论】:

  • 第 0 行第 2 列呢?那不应该也是0吗?
  • 不,因为它不是最后一个值。第 0 行第 10 列是该行的最后一个值,它被转换为 0。我在第 10 列之后还有其他行,我不想更改

标签: python pandas dataframe


【解决方案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')

【讨论】:

  • 这个问题是它会占用整个数据框,在第 10 列之后有更多列,我想你是从我的原始帖子中编辑的
  • @codingtherapy 正确。因为我不希望它有损您问题的意图。我将添加一个编辑来解决这个问题。
  • @codingtherapy 完成。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-19
  • 2015-08-08
  • 2019-10-18
相关资源
最近更新 更多