使用基于条件的其他列值替换大量列中的值

时间:2017-01-27 13:31:29

标签: python pandas dataframe

我有这些数据:

id   |  d1   |  d2  |  d3  | .... |  d64   | FINAL_GRADE
1    |  0    |  15  |  0   | .... |  23    | 95
2    |  8    |  0   |  12  | .... |  0     | 75   

我想用FINAL_GRADE列中的相应值替换每行中的所有非零值,并获取此表:

id   |  d1   |  d2  |  d3  | .... |  d64   | FINAL_GRADE
1    |  0    |  95  |  0   | .... |  95    | 95
2    |  75   |  0   |  75  | .... |  0     | 75   

这是我的代码:

df[df.ix[:, 1:63] != 0] = df['FINAL_GRADE']

但是,我收到此错误:TypeError: Cannot do inplace boolean setting on mixed-types with a non np.nan value

我想知道我的代码是否有任何问题?或者我的做法完全错了。我感谢任何帮助!

2 个答案:

答案 0 :(得分:3)

一种可能性是在创建的布尔掩码上使用DF.mask()方法。

使用.ix设置值失败,这可能是因为您在混合dtypesfloat - 的列子集上运行 - 由于生成bool掩码和子集操作& int - 要查看 FINAL_GRADE 中的值。)

这将是TypeError生成的主要原因。

<强> 步骤:

1)使用str.startswith选择以char d 开头的列来设置数据框。

2)使用DF.mask表示此子集中的值不为零的条件,我们通过指定{{1}将其替换为 FINAL_GRADE 中的内容。 }。

3)最后,使用axis=0DF)连接 id FINAL_GRADE 和蒙版pd.concat列。

axis=1

enter image description here

答案 1 :(得分:1)

以下可能稍微粗略而不是严格必要,但我认为它适合您的问题:

for _, row in df.iterrows():
    row[0:-1][row != 0] = row.FINAL_GRADE

请注意,我在这里做了几件事,所以有些注意事项:

  1. row[0:-1]将解决除最后一行之外的所有行项,因此在这种情况下使用整数索引时不需要.ix,并且您不会遇到完全 64列。
  2. 我正在遍历所有行,这通常不被认为是最有效的处理方式,但我发现它对于像你这样不会重复数百次的高性能计算的情况而言是可读的并且足够好。
  3. _是忽略变量的惯例,在这种情况下,变量是iterrows()自动给我的行索引。
  4. 尝试使用超过.loc的{​​{1}},因为它利用了标记数据的语义优势。
  5. 我试着想出一个没有for循环的解决方案,这个循环被认为是pythonic而且不是太做作或不可读。

    修改 在我看来,发现一个单行,既可读又简单/通用,足以应用于其他/类似问题:

    .ix