【问题标题】:Vectorized update to pandas DataFrame?对 pandas DataFrame 的矢量化更新?
【发布时间】:2015-12-22 23:34:23
【问题描述】:

我有一个数据框,我想用数组中的一些值更新一列。然而,该数组与数据帧的长度不同,但我有要更新的数据帧行的索引。

我可以通过循环遍历行(如下)来做到这一点,但我希望有一种更有效的方法可以通过矢量化方法来做到这一点,但我似乎无法获得正确的语法。

在下面的示例中,我只是用nan 填充列,然后通过循环直接使用索引。

df['newcol'] = np.nan

j = 0
for i in update_idx:
    df['newcol'][i] = new_values[j]
    j+=1

【问题讨论】:

  • 这是一个数组还是一个系列/df?您可以直接分配系列:df['newcol'] = new_values 或构造一个系列:df['newcol'] = pd.Series(new_values) new_values 中的额外行将被忽略
  • 要更新的值当前位于数组中,但如果解决方案需要,可以进行转换。也许我错了,但您的解决方案不会忽略我只想更新某些索引的事实吗?例如,我可能想更新第 2、第 8、第 20 .. 索引(在示例中这些在 update_idx 中),但您的方法不会只更新数据帧的前 N ​​行(其中 N 是 new_values 的长度) ?
  • 那么我认为df.loc[update_idx, 'new_col'] = new_values 应该可以工作
  • 完美 - 非常感谢。如果您愿意将其作为答案提交,我可以接受!

标签: python pandas vectorization


【解决方案1】:

如果您已经有一个索引列表,那么您可以使用loc 执行标签(行)选择,您可以传递新的列名,如果您现有的行未被选择,这些将分配NaN

df.loc[update_idx, 'new_col'] = new_value

例子:

In [4]:
df = pd.DataFrame({'a':np.arange(5), 'b':np.random.randn(5)}, index = list('abcde'))
df

Out[4]:
   a         b
a  0  1.800300
b  1  0.351843
c  2  0.278122
d  3  1.387417
e  4  1.202503

In [5]:    
idx_list = ['b','d','e']
df.loc[idx_list, 'c'] = np.arange(3)
df

Out[5]:
   a         b   c
a  0  1.800300 NaN
b  1  0.351843   0
c  2  0.278122 NaN
d  3  1.387417   1
e  4  1.202503   2

【讨论】:

  • loc 是否使用矢量化方法来访问 numpy 元素?我听说应该避免使用 loc 以防止在引擎盖下使用 for 循环。我被告知要使用 numpy [Boolean] 样式索引。谢谢:)
  • 不,loc 做基于标签的索引,它与矢量化无关。对 loc 结果的操作可能会或可能不会被矢量化。不知道你听到的内容是什么,但这个假设是错误的
  • 这个时间和你一致 testa = pd.DataFrame(np.arange(10000000),columns =['q']) %timeit testb = testa.loc[testa.q>6] %timeit testc = testa[testa.q>7] # 1 个循环,最好的 3:每个循环 207 毫秒 #1 个循环,最好的 3:每个循环 208 毫秒
  • 好的。我从你说的基于标签的索引不是由 for 循环 for loc 完成的。什么会阻止该操作被矢量化?谢谢
  • 使用 .apply 或使用 for 或 iterrows 进行迭代不是矢量化的。抱歉,如果您有任何问题,那么您应该发布一个问题,使用 cmets 作为讨论对 SO 来说是不好的形式
猜你喜欢
  • 2023-03-20
  • 2017-09-26
  • 2021-02-07
  • 1970-01-01
  • 2015-01-02
  • 2021-01-18
  • 1970-01-01
  • 2021-05-17
  • 2023-03-30
相关资源
最近更新 更多