2017-02-20 40 views
1

我正在嘗試爲熱圖或3D繪圖準備一些數據。總的想法是我有一些函數z = f(x,y),其中z是特定單元格的值,其中x爲列值,y爲索引值。Pandas DataFrame:將索引和列值作爲參數以cell-wise方式應用

我目前的做法是遍歷其已經具備了所需的結果數據框:

import numpy as np 
import pandas as pd 


def my_fun(a, b): 
    return(a**2 + b**3) 

index = [i for i in np.arange(25.0, 100.0, 25.0)] 
columns = [i for i in np.arange(150.0, 600.0, 150.0)] 
df = pd.DataFrame(np.zeros((3, 3)), index=index, columns=columns) 

for idx in index: 
    for col in columns: 
    df.loc[idx, col] = my_fun(idx, col) 

print(df) 

和產量:

 150.0  300.0  450.0 
25.0 3375625.0 27000625.0 91125625.0 
50.0 3377500.0 27002500.0 91127500.0 
75.0 3380625.0 27005625.0 91130625.0 

但遍歷數據幀可能是不正確的(矢量)處理這個問題的方法,我正在尋找一些漂亮的組合apply/applymap/map

有什麼辦法以更聰明/矢量化的方式獲得相同的結果?

提前致謝!

回答

4

您可以使用:

#if need only some easy arithmetic operation like sum 
print (df.apply(lambda x: x.index + x.name, axis=1)) 
    1 2 3 
1 2 3 4 
2 3 4 5 
3 4 5 6 

如果需要使用標量的函數,可以使用stack for Series,轉換爲df,應用函數並返回unstack

df1 = df.stack().to_frame().apply(lambda x: my_fun(x.name[0], x.name[1]), axis=1).unstack() 
print (df1) 
    1 2 3 
1 2 3 4 
2 3 4 5 
3 4 5 6 

對於測試是最好的,而不是lambda使用像一些自定義功能:

def f(x): 
    print (x.name) 
    print (x.index) 
    return x.index + x.name 
1 
Int64Index([1, 2, 3], dtype='int64') 
1 
Int64Index([1, 2, 3], dtype='int64') 
2 
Int64Index([1, 2, 3], dtype='int64') 
3 
Int64Index([1, 2, 3], dtype='int64') 

print (df.apply(f, axis=1)) 

    1 2 3 
1 2 3 4 
2 3 4 5 
3 4 5 6 
+0

工程就像一個魅力!謝謝。我完全錯過了,我可以使用單元格的.name和.index屬性! –

+0

謝謝。如果你覺得它有用,你也可以提出這個問題,因爲我沒有在我的搜索中找到任何答案 –

+0

還有一個問題:是否也可以將其他參數與默認參數傳遞給f(),如f (x,y = 0.5,z = 4)? –

0

事實上,你可以簡單地利用了apply功能操作逐列明知列索引始終可用,因爲該列是pandas.Series

import numpy as np 
import pandas as pd 


def my_fun(col): 
    # both are numpy arrays, col.values gives the inner value of the whole column 
    # operations here use the fast numpy primitives 
    return col.index + col.values 

index = [i for i in range(1, 4)] 
columns = ['col' + str(i) for i in range(1, 4)] 
df = pd.DataFrame(np.random.randint(1, 10, (3, 3)), index=index, columns=columns) 

col_names = ['col1', 'col2'] # alternatively you can use an array of columns indices such as [1, 2] 
df[col_names].apply(my_fun) 
print(df) 
+0

我覺得這隻能如果我要根據前值的指標值而不是基於計算單元格的值在列值上。也許我的問題沒有明確闡述。我已經修改了代碼! –

相關問題