遍历行时如何使用掩码更新 DataFrame 中的值
How do I update value in DataFrame with mask when iterating through rows
使用下面的代码,我试图在触发 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])
回答您的问题
编辑:根据评论更改了建议
代码的赋值部分 df_test['placed'][mask][j] = 1
使用所谓的 chained indexing。简而言之,您的作业仅更改立即丢弃的 DataFrame 的临时副本,而不会更改原始 DataFrame。
为避免这种情况,赋值时的经验法则是:在单个 DataFrame 上仅使用一组方括号。对于您的问题,应该如下所示:
df_test.loc[mask.nonzero()[0][j], 'placed'] = 1
(我知道 mask.nonzero()
使用两组方括号;实际上 nonzero()
returns 一个元组,该元组的第一个元素是一个 ndarray .但是dataframe只用了一组,那才是最重要的部分。)
其他一些注意事项
我有一些关于使用 pandas
(& numpy
) 的笔记。
Pandas 和 NumPy 都有一个叫做 广播 的特性。基本上,如果您要为整个数组分配一个值,则不需要先创建一个相同大小的数组;您可以只分配单个值,pandas/NumPy 会自动为您计算出如何应用它。所以你的代码的第一行可以用df_test['placed'] = 0
代替,它完成同样的事情。
一般来说 在使用 pandas & numpy 对象时,循环不好;通常你可以找到一种方法来使用广播、逐元素操作和布尔索引的某种组合做一个循环会做的事情。由于这些功能的设计方式,它 运行 也会快很多。不幸的是,我对 lm.predict
方法不够熟悉,但您可以完全避免此代码的整个 for
循环。
使用下面的代码,我试图在触发 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])
回答您的问题
编辑:根据评论更改了建议
代码的赋值部分 df_test['placed'][mask][j] = 1
使用所谓的 chained indexing。简而言之,您的作业仅更改立即丢弃的 DataFrame 的临时副本,而不会更改原始 DataFrame。
为避免这种情况,赋值时的经验法则是:在单个 DataFrame 上仅使用一组方括号。对于您的问题,应该如下所示:
df_test.loc[mask.nonzero()[0][j], 'placed'] = 1
(我知道 mask.nonzero()
使用两组方括号;实际上 nonzero()
returns 一个元组,该元组的第一个元素是一个 ndarray .但是dataframe只用了一组,那才是最重要的部分。)
其他一些注意事项
我有一些关于使用 pandas
(& numpy
) 的笔记。
Pandas 和 NumPy 都有一个叫做 广播 的特性。基本上,如果您要为整个数组分配一个值,则不需要先创建一个相同大小的数组;您可以只分配单个值,pandas/NumPy 会自动为您计算出如何应用它。所以你的代码的第一行可以用
df_test['placed'] = 0
代替,它完成同样的事情。一般来说 在使用 pandas & numpy 对象时,循环不好;通常你可以找到一种方法来使用广播、逐元素操作和布尔索引的某种组合做一个循环会做的事情。由于这些功能的设计方式,它 运行 也会快很多。不幸的是,我对
lm.predict
方法不够熟悉,但您可以完全避免此代码的整个for
循环。