【问题标题】:How do I update value in DataFrame with mask when iterating through rows遍历行时如何使用掩码更新 DataFrame 中的值
【发布时间】:2019-05-16 07:00:21
【问题描述】:

使用下面的代码,当触发 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])

【问题讨论】:

    标签: python pandas dataframe mask


    【解决方案1】:

    回答您的问题

    编辑:根据 cmets 更改建议

    代码的赋值部分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,它完成了同样的事情。

    • 一般来说在处理 pandas 和 numpy 对象时,循环不好;通常你可以找到一种方法来使用广播元素操作布尔索引的组合来完成循环的工作。而且由于这些功能的设计方式,它的运行速度也会快得多。不幸的是,我对lm.predict 方法说的不够熟悉,但您可能可以完全避免整个for-loop。

    【讨论】:

    • 不幸的是,输出仍然不起作用,虽然它更新了一些值到 1,但它应用的 1 比代码中实际预期的要多得多,我想我可能需要通过某个地方传递 [j] ,但是当我这样做时: ValueError: cannot reindex from a duplicate axis
    • 是的,听起来不错 T-T j 是 DataFrame 的行索引吗?如果是这样,请尝试df_test.loc[j, 'placed']。 (基本思想是,您应该只使用一组方括号。)
    • 我想我需要两者,掩码通过 set() 将“id”分组在一起,然后 j 返回 max() 预测的每组中的位置。有没有办法在 .loc[] 中同时通过?
    • 当然,我刚刚在我的答案中编辑了我认为应该起作用的内容(如果我正确理解了j)。
    猜你喜欢
    • 2021-02-01
    • 2018-10-16
    • 2022-10-25
    • 2015-08-20
    • 2012-05-30
    相关资源
    最近更新 更多