2017-04-03 124 views
1
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]) 

表達選項之外,我發現了一種方法,用我的值集中的值更新我的數據框,在我的索引集中指定的位置,這種方法很有效,但它有點慢(而且很醜!)。

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

這是一個問題,因爲在我的現實生活中,我有數千(數百萬?)的更新要執行。

我想找到的是某種numpy加速的單次更新(即沒有列表理解),它將更新轉換爲適當的目標位置,而不會覆蓋非索引中的現有值位置。

有什麼想法嗎?

回答

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循環。

+0

只是門票,三江源 - 是的,我有種直覺地感到列表理解是不正確的方式去。你的解釋有助於把這種直覺背後的背景,所以謝謝你。 –