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加速的单次更新(即没有列表理解)将更新放到适当的目标位置,而不会覆盖非现有值索引位置。
有什么想法吗?
答案 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循环。