繁体   English   中英

根据条件用另一列值替换大量列中的值

[英]Replacing values in large number of columns with another column value based on a condition

我有此数据:

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

我想知道我的代码是否有任何问题? 否则我的方法是完全错误的。 感谢您的帮助!

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

使用.ix用于设置值这里大概是失败,因为你在具有混合列的子集数工作dtypesfloat -由于布尔面罩和子集操作和产生int -在FINAL_GRADE值在要查找)。

这将是产生TypeError主要原因。

脚步:

1)通过使用str.startswith选择以char d开头的列来对数据str.startswith进行str.startswith

2)在此子集中的值不为零的条件下使用DF.mask ,通过指定axis=0 ,将它们替换为FINAL_GRADE行中存在的内容。

3)最后,使用pd.concataxis=1 )按列连接idFINAL_GRADE和蒙版DF


sub_df = df[df.columns[df.columns.str.startswith('d')]]
mask_df = sub_df.mask(sub_df != 0, df['FINAL_GRADE'], axis=0)
pd.concat([df['id'], mask_df, df['FINAL_GRADE']], axis=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而不是.ix因为它利用了标记数据给您的语义优势。

我将尝试考虑一个没有for循环的解决方案,该解决方案被认为是pythonic的,并且不是太人为或难以理解。

编辑:找到了我认为可读性,简单性/通用性足以应用于其他/类似问题的单线:

df.ix[:, 0:-1] = df.ix[:, 0:-1].where(df == 0, df.FINAL_GRADE, axis=0)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM