遍历行时如何使用掩码更新DataFrame中的值

时间:2018-12-15 03:43:29

标签: python pandas dataframe mask

使用以下代码,当触发if语句并放置预测时,我试图将列df_test['placed']更新为= 1。虽然我无法正确更新此代码,但是代码可以编译,但对于所放置的各个预测都不会更新为= 1。

df_test['placed'] = np.zeros(len(df_test))
for i in set(df_test['id']) :
    mask = df_test['id']==i
    predictions = lm.predict(X_test[mask])
    j = np.argmax(predictions)
    if predictions[j] > 0 :
        df_test['placed'][mask][j] = 1
        print(df_test['placed'][mask][j])

1 个答案:

答案 0 :(得分:2)

回答您的问题

编辑:根据评论更改了建议

您代码的分配部分df_test['placed'][mask][j] = 1使用的是chained indexing。简而言之,您的分配只会更改DataFrame的临时副本,该副本会立即被丢弃,而不会更改原始DataFrame。

为避免这种情况,分配时的经验法则是:在单个DataFrame上仅使用一组方括号。对于您的问题,应该看起来像这样:

df_test.loc[mask.nonzero()[0][j], 'placed'] = 1

(我知道mask.nonzero()使用了两组方括号;实际上nonzero()返回了一个元组,而该元组的第一个元素是一个ndarray。但是数据帧仅使用一组,这是重要的部分。)

其他一些笔记

我在使用pandas(&numpy)时有几点注意事项。

  • Pandas和NumPy都具有称为广播的功能。基本上,如果您要为整个数组分配单个值,则无需先创建相同大小的数组;您只需分配单个值,pandas / NumPy就会自动为您找出如何应用它。因此,您的代码的第一行可以替换为df_test['placed'] = 0,并且可以完成相同的操作。

  • 通常来说在处理熊猫和numpy对象时,循环不好;通常,您可以找到一种方法来使用广播元素逐项操作布尔索引的某种组合来执行循环。由于这些功能的设计方式,它的运行速度也将大大提高。不幸的是,我对lm.predict方法并不熟悉,但是您可以完全避免针对此代码的整个for循环。