Pandas:将索引的值列表应用于数据帧

时间:2017-04-03 18:31:20

标签: python pandas numpy

import pandas as pd
import numpy as np

我有一个数据框:

my_df = pd.DataFrame({'target': [0   ,0   ,0   ,0   , 300, 400, 500, 600, 0],
                   'class' : [0  ,0   ,0   ,0   ,   1,   1,   1,   1,   0],
                   'feature':[12 ,13  ,13  ,200 , 900, 800, 600, 600,  12]})

我的流程已生成一组索引更新,表示为一对列表:

update_index  = [0 ,  1,  2,   3,   8]
update_values = [20, 25, 25, 150,  25]

或者,我可以将这些表示为元组列表:

update_tuples = [(0,20), (1,25), (2,25), (3,150), (8,25)]

或者,理想情况下,我希望能够将它们表达为一对numpy数组 - 因为这更有可能是我生成它们的形式。

update_index_array  = np.array([0 ,  1,  2,   3,   8])
update_values_array = np.array([20, 25, 25, 150,  25])

除了表达式选项之外,我找到了一种方法,用我的value-set中的值在我的索引集中指定的位置更新我的数据帧,这样可行,但它有点慢(和难看!)。

[my_df.set_value(i,'target',v) for i,v in update_tuples]

这是一个问题,因为在我的实际例子中,我有数千(数百万?)个更新要执行。

我想要找到的是某种numpy加速的单次更新(即没有列表理解)将更新放到适当的目标位置,而不会覆盖非现有值索引位置。

有什么想法吗?

1 个答案:

答案 0 :(得分:3)

是的,这肯定是而不是如何在pandas中执行此操作。而是使用索引分配:

>>> my_df.loc[update_index_array, 'target'] = update_values_array
>>> my_df
   class  feature  target
0      0       12      20
1      0       13      25
2      0       13      25
3      0      200     150
4      1      900     300
5      1      800     400
6      1      600     500
7      1      600     600
8      0       12      25
>>>

顺便说一句,你应该从不使用这样的理解:

[my_df.set_value(i,'target',v) for i,v in update_tuples]

列表推导不仅仅是编写for循环的奇特方式,而是用于创建新列表。这是将函数式编程结构(列表理解)与状态变化即my_df.set_value混合。那简直是语无伦次的风格。但更糟糕的是,它也是浪费,因为您正在创建一个对同一数据帧的无用的引用列表。相反,只需使用for循环。类似的情况可能是:

>>> my_list = []
>>> [my_list.append(i) for i in range(5)]
[None, None, None, None, None]
>>> my_list
[0, 1, 2, 3, 4]
不要这样做。如果你打算使用副作用,只需使用for循环。