2016-09-29 47 views
2

我目前正在玩一些涉及熊貓的事情,我想知道什麼是解決以下問題的最有效方法。這是一個簡單的例子。使用熊貓「申請map」訪問索引/列?

說我有一個數據幀的一些數據:

import pandas as pd 
import numpy as np 
df = pd.DataFrame(np.random.randint(0,10,size=(10, 4)), columns=['a','b','c','d'], 
        index=np.random.randint(0,10,size=10)) 

這個數據看起來是這樣的:

a b c d 
1 0 0 9 9 
0 2 2 1 7 
3 9 3 4 0 
2 5 0 9 4 
1 7 7 7 2 
6 4 4 6 4 
1 1 6 0 0 
7 8 0 9 3 
5 0 0 8 3 
4 5 0 2 4 

現在我想一些功能應用到每個值在數據幀(例如下面的那個),並獲取數據幀作爲結果輸出。棘手的部分是我正在應用的函數取決於我目前所處的索引值。

def f(cell_val,row_val): 
    try: 
     return cell_val/row_val 
    except ZeroDivisionError: 
     return -1 

通常情況下,如果我想給一個函數應用到數據幀中的每個單獨的小區,我只想叫applymap的「F」。即使我必須傳入第二個參數(在本例中爲row_val),如果參數是一個固定數字,我可以只寫一個lambda表達式,如「lambda x:f(x,i)」,其中i是固定的我想要的號碼。但是,我的第二個參數取決於我當前正在調用該函數的數據框中的行,這意味着我不能只使用applymap。

我該如何有效地解決這樣的問題?我可以想到幾種方法來做到這一點,但他們都沒有感覺到「正確」。我可以遍歷每個單獨的值並逐個替換它們,但這看起來非常尷尬和緩慢。我也可以做一些事情,比如創建一個完全獨立的包含(單元值,行值)元組的數據框,並在我的元組數據框中使用內置的pandas applymap。但是,這看起來很詭異,我還創建了一個完全獨立的數據框,作爲一個額外的步驟。

必須有一個更好的解決方案(這是一個快速的解決方案,將不勝感激,因爲有可能我的數據幀變得非常大)。

+0

對不起,您在:'df.div(df.index.to_series(),axis = 0)'? – EdChum

回答

2

IIUC可以使用divaxis=0再加上你需要使用to_seriesIndex對象轉換爲Series對象:

In [121]: 
df.div(df.index.to_series(), axis=0).replace(np.inf, -1) 

Out[121]: 
      a   b   c   d 
1 0.000000 0.000000 9.000000 9.000000 
0 -1.000000 -1.000000 -1.000000 -1.000000 
3 3.000000 1.000000 1.333333 0.000000 
2 2.500000 0.000000 4.500000 2.000000 
1 7.000000 7.000000 7.000000 2.000000 
6 0.666667 0.666667 1.000000 0.666667 
1 1.000000 6.000000 0.000000 0.000000 
7 1.142857 0.000000 1.285714 0.428571 
5 0.000000 0.000000 1.600000 0.600000 
4 1.250000 0.000000 0.500000 1.000000 

此外,通過零個結果分工inf需要調用replace,以取代那些行與-1

+0

這適用於示例情況,但如果我的功能比簡單的分區更復雜,那麼在某些時候可能會失敗並出現錯誤?然後我無法在我的數據框上調用pandas.div。 –

+0

你將需要解釋這將如何失敗,因爲這處理'0'劃分 – EdChum

+0

例如,說,而不是執行劃分我的功能在另一個數據框做了查找,我需要用別的東西替換IndexErrors。 類似於「def f(x,y):try:return df2.iloc [x,y]」IndexError:return -1「 –

0

以下是如何將索引添加到數據框中

pd.DataFrame(df.values + df.index.values[:, None], df.index, df.columns)