簡體   English   中英

將函數應用於每個組:TypeError: unhashable type: 'numpy.ndarray'

[英]Apply Function to every group: TypeError: unhashable type: 'numpy.ndarray'

我正在嘗試為每個組做一個曲線擬合,並為每個組獲得 c、a、b 的結果。

我是這樣試的:

x=df.T.iloc[1]
y=df.T.iloc[2]

def logifunc(x,c,a,b):
    return c / (1 + (a) * np.exp(-b*(x)))

df.groupby('Seriennummer').apply(curve_fit(logifunc, x, y, p0=[110,400,-2]))

但我收到錯誤:

類型錯誤:不可散列類型:'numpy.ndarray'

這是我的 df 的一部分,有一百萬行:

    Seriennummer    mrwSmpVWi   mrwSmpP
1915    701091.0    1.8   4.0
1916    701085.0    2.0   2.0
1917    701089.0    1.7   0.0
1918    701087.0    1.8   3.0
1919    701090.0    1.8   0.0
1920    701088.0    2.4   0.0
1921    701086.0    2.7   5.0
1922    701092.0    1.1   0.0
1923    701085.0    2.0   2.0
1924    701089.0    2.0   10.0
1925    701091.0    0.8   0.0
1926    701087.0    2.3   10.0
1927    701090.0    1.6   1.0
1928    701092.0    2.2   6.0
1929    701086.0    1.5   0.0
1930    701088.0    2.1   3.0

你的代碼中有一個奇怪的地方是:

  • 盡管您按Seriennummer執行分組,
  • 然后,對於每個組,您嘗試對來自完整DataFrame 的數據執行曲線擬合。

為了獲得正確的結果,您應該只對當前組執行曲線擬合。 就像是:

import scipy.optimize as opt

result = df.groupby('Seriennummer').apply(lambda grp:
    opt.curve_fit(logifunc, grp.mrwSmpVWi, grp.mrwSmpP, p0=[110, 400, -2]))

我的lambda函數類似於其他答案中提到的包裝器,其他參數在此函數中進行了硬編碼。

由於您的數據樣本每組僅包含 2 行,因此我准備了自己的 DataFrame:

      Seriennummer  mrwSmpVWi  mrwSmpP
1915      701091.0        1.8      4.0
1916      701091.0        1.6      3.4
1917      701091.0        1.4      3.0
1918      701091.0        1.0      1.5
1919      701091.0        0.8      0.0
1920      701085.0        2.0      2.0
1921      701085.0        2.5      3.0
1922      701085.0        3.0      3.5
1923      701085.0        3.6      4.2

並運行上面的代碼,沒有錯誤。

為了以易於評估的方式打印結果,我運行:

for k, v in result.iteritems():
    print(f'Group {k:}:\n{v[0]}\n{v[1]}')

得到:

Group 701085.0:
[ 4.66854588 24.45419288  1.47315989]
[[ 3.43664761e-01 -1.05587500e+01 -2.65359878e-01]
 [-1.05587500e+01  4.60108288e+02  1.03214386e+01]
 [-2.65359878e-01  1.03214386e+01  2.40785819e-01]]
Group 701091.0:
[  3.89988734 617.72482118   5.54935645]
[[ 3.42006760e-01 -6.02519226e+02 -1.11651569e+00]
 [-6.02519226e+02  2.43770095e+06  3.83083902e+03]
 [-1.11651569e+00  3.83083902e+03  6.28930797e+00]]

首先在我的數據上重復上述過程,然后在您自己的數據上重復上述過程。

按照截至 11:03Z 的評論進行編輯

閱讀scipy.optimize.curve_fit的文檔。 結果的描述(每次調用)包含:

  • popt - 參數(擬合曲線的)的最佳值,
  • pcov2 - popt 的估計協方差。

如果你想要為每個組POPT並不在乎pcov2,那么lambda函數應該從(2元),結果只返回的第一個元素:

result = df.groupby('Seriennummer').apply(lambda grp: opt.curve_fit(
    logifunc, grp.mrwSmpVWi, grp.mrwSmpP, p0=[110, 400, -2])[0])

(注意[0]在末尾添加)。

一些注意事項:

  1. 請注意,您傳遞給curve_fit GroupBy對象的參數實際上是調用curve_fit函數的結果, curve_fit函數返回一個ndarray GroupBy.apply的第一個參數是一個需要返回熊貓對象(DataFrame,標量系列)的可調用對象,這就是您收到該錯誤的原因。

  2. 我不確定您要做什么,但我認為它會根據您編寫的函數為每個組制作一條曲線。

如果是這種情況,我建議您將該功能包裝在另一個函數中並將其傳遞給 apply 方法。

def wrapper(df-of-group-by, *args):
    # somehow work with your given DataFrame to achieve what you are looking for
    # you can also print what-ever and export images
    # the important thing is that you return a DataFrame back

# usage:
ohlala.groupby('Seriennummer').apply(wrapper, YOUR-ARGS)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM