2017-07-07 80 views
1

我有一個帶有541列的DataFrame df,並且我需要將其列名的所有唯一對保存到單獨的DataFrame的行中,每個行重複8次。訪問Pandas DataFrame的最快捷方式是什麼?

我想我會創建一個空的DataFrame fp,通過df的列名稱的雙重循環,插入到每第8行,並用最後一個可用值填充空白。

當我試圖做到這一點,雖然我感到困惑的是,它花了多長時間。在541欄中,我只需要寫146,611次,但是花費了20分鐘以上。這對於數據訪問來說似乎太過分了。問題在哪裏,我該如何解決?與Pandas相比,它需要更少的時間來產生與列的相關矩陣,所以我必須做出錯誤的事情。

這裏是我的意思重複的例子:

fp = np.empty(shape = (146611, 10)) 
fp.fill(np.nan) 

fp = pd.DataFrame(fp) 

%timeit for idx in range(0, len(fp)): fp.iloc[idx, 0] = idx 

# 1 loop, best of 3: 22.3 s per loop 

回答

6

不要做ILOC /祿/鏈接索引。單獨使用NumPy接口可將速度提高約180倍。如果您進一步刪除元素訪問權限,我們可以將此限制爲180,000x。

fp = np.empty(shape = (146611, 10)) 
fp.fill(np.nan) 

fp = pd.DataFrame(fp) 

# this confirms how slow data access is on my computer 
%timeit for idx in range(0, len(fp)): fp.iloc[idx, 0] = idx 

1 loops, best of 3: 3min 9s per loop 

# this accesses the underlying NumPy array, so you can directly set the data 
%timeit for idx in range(0, len(fp)): fp.values[idx, 0] = idx 

1 loops, best of 3: 1.19 s per loop 

這是因爲在Python層有大量的代碼用於這種創建索引,每個循環的時間爲10μs。應該使用Pandas索引來檢索整個數據子集,然後用它們對整個數據幀進行矢量化操作。單個元素訪問是冰河的:使用Python字典會使您的性能提高> 180倍。

當您訪問列或行而不是單個元素時,事情會變得更好:更好的3個數量級。

# set all items in 1 go. 
%timeit fp[0] = np.arange(146611) 
1000 loops, best of 3: 814 µs per loop 

道德

不要試圖通過鏈接的索引來訪問單個元素,loc,或iloc。從Python列表(或者如果性能絕對關鍵時是C接口)在單個分配中生成NumPy數組,然後在整個列或數據框上執行操作。

使用NumPy數組並直接在列而不是單個元素上執行操作,我們得到了高達180,000+倍的性能提升。不是太寒酸。

相關問題