使用 iterrows() 时的持久性问题

Posted

技术标签:

【中文标题】使用 iterrows() 时的持久性问题【英文标题】:Persistence problems when using iterrows() 【发布时间】:2014-04-14 05:41:54 【问题描述】:

我相信有人也在this thread 中报告过,使用iterrows() 填充数据框可能会导致持久性问题。例如。像这样简单的东西:

my_dataframe = pd.DataFrame(np.NaN, index = xrange(5),columns=['foo',  'bar'])

for ix, row in my_dataframe.iterrows():
  row['foo'] = 'Hello'

导致数据框没有变化:

> my_dataframe
    foo  bar
0   NaN  NaN
1   NaN  NaN
2   NaN  NaN
3   NaN  NaN
4   NaN  NaN

我没有收到任何警告,也没有异常等。这是故意的吗?它是一个错误吗?故意的?到底发生了什么?

以上是 Pandas 的最新稳定版本,0.13.1。

【问题讨论】:

你这里的用例是什么,通常你可以避免迭代行。 谢谢@Andy - 我的计算是特定于行和组的(即,有问题的列捕获了与组相关的行的比较)。更具体地说,每一行都有一个权重,它是组的最小值和最大值之间的线性插值(在其他列上)。所以我目前的工作流程是:首先将数据分组到分区中,然后遍历每一行计算每一行的权重。也就是说,您可能是对的 - 可能有一种方法可以做到这一点而无需迭代 对不起 - 我忘了提到你的全名@AndyHayden 听起来很棘手......但有可能。如果你能想出一个玩具例子/想要的结果,也许值得问一个关于如何做的问题:) 【参考方案1】:

您正在更改行的类型,因此它正在修改副本。

在这种情况下,保持 dtype 的东西会起作用:

In [11]: for ix, row in my_dataframe.iterrows():
   ....:       row['foo'] = 1

不能保证这种行为,最好使用 loc 或直接分配列进行分配:

In [12]: row['foo'] = 'Hello'  # works

In [13]: row.loc[:, 'foo'] = 'Hello'  # works

见returning a view vs a copy in the docs。

我应该补充一点,您可以通过分配给原始帧(使用 loc/ix)来做到这一点,但是您可以(并且应该)通常通过矢量化解决方案而不是迭代每个解决方案来避免这种情况行:

for ix, row in my_dataframe.iterrows():
      my_dataframe.ix[ix, 'foo'] = 'Hello'  # works

【讨论】:

以上是关于使用 iterrows() 时的持久性问题的主要内容,如果未能解决你的问题,请参考以下文章

在这个例子中避免使用 iterrows 的好方法是啥?

在特定索引上启动 iterrows() 循环

使用JSF Converter时的延迟加载异常(指一个集合)

iterrows 的更快替代方案

从 Pandas 中的 iterrows() 获取行位置而不是行索引

在(持久切换)jQuery中访问其他页面时的持久内容