[英]Applying a function depending of index and column of a dataframe to a dataframe
我有一個 dataframe df
其索引為[x[0], ..., x[N]]
列為[y[0], ..., y[M]]
其數據為z[i,j]
的二維數組z[i,j]
的。
我有一個 python function def f(x, y, z)
的 3 個浮點變量,我想計算f(x[i], y[j], z[i,j])
的二維數組使用 numpy 和/或 pandas 的最快方法,但我不知道該怎么做。
我看到了df.transform
方法,但它似乎不允許依賴於df
或者至少我不知道如何提供這樣的 lambda。
df
和f
的詳細信息:
我的df
是怎么獲得的? 我在 N = 5000 和 M = 5000 的網格上使用密集數值 python 矢量化 function 在 45 分鍾的計算過程中創建了它,我對它進行了“ to_csv
”。 現在,當我想使用它時,我使用read_csv
。
現在我的 function f
是一個相當復雜的數字C++
function 我用 pybind11 暴露給 python (我為了完整性而放置標簽)並且我現在不想以“numpy vectorizable fashion”重寫,因為它是超-優化且非常快。 給定x,y
function f
以數值方式求解(迭代求根器)具有參數x,y,z
和未知Z
的方程,方程的根為f(x,y,z)
。
你可以做一個pd.melt :
df.reset_index().rename(columns={'index':'x'}).melt(var_name='y', value_name='z', id_vars='x')
它實質上將 dataframe 轉換為長格式,使每一行具有三個條目:x、y 和 z。
如果您不想重寫 function,那么使用循環for
應用 function 似乎是一種簡單的方法。 你可以這樣做
idx = df.index
cols = df.columns
vals = df.to_numpy()
r = [
[f(x,y,z) for y, z in zip(cols, vals[i])]
for i, x in enumerate(idx)
]
# if you want to recreate a dataframe
df_root = pd.DataFrame(data=r, index=idx, columns=cols)
索引上有一個列表理解,其中同時包含列和行值的列表理解。 vals[i]
訪問 position i
行中的值。 結果r
是一個長度為行數 (N) 的列表,每個項目都是一個長度為列數 (M) 的列表。 您不需要特別使用此結構,但這是構建與原始數據具有相同索引列的 dataframe 的簡單方法。
請注意,它仍然會很長,即使 f 已優化,您仍有大約 2500 萬次操作要做。
我終於這樣做了:
matrix = df_prices.values
x_matrix = np.tile(x, (y.size, 1)).transpose()
y_matrix = np.tile(y, (x.size, 1))
f_vect = np.frompyfunc(f, 3, 1)
res = f_vect (matrix , x_matrix , y_matrix )
在性能方面,它是最佳的,而不必自己對超優化但未矢量化的根求解器 f 進行矢量化——順便說一句,它是一個 C++ function,我使用 pybind11 向 python 公開。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.