DF.Apply出力の新しい列の引数としての特定のPandas列 -- python フィールド と pandas フィールド と numpy フィールド と scikit-learn フィールド 関連 問題

Specific pandas columns as arguments in new column of df.apply outputs












1
vote

問題

日本語

以下のようにパンダデータフレームを与えられる:

<事前> <コード> import pandas as pd from sklearn.metrics import mean_squared_error df = pd.DataFrame.from_dict( {'row': ['a','b','c','d','e','y'], 'a': [ 0, -.8,-.6,-.3, .8, .01], 'b': [-.8, 0, .5, .7,-.9, .01], 'c': [-.6, .5, 0, .3, .1, .01], 'd': [-.3, .7, .3, 0, .2, .01], 'e': [ .8,-.9, .1, .2, 0, .01], 'y': [ .01, .01, .01, .01, .01, 0], }).set_index('row') df.columns.names = ['col']

RMSE値の新しい列を作成したい( scikit-learn )引数の特定の列を使用します。すなわち、列<コード> y_true = df['a','b','c'] Vs y_pred = df['x','y','x'] 。反復アプローチを使用してこれは簡単でした。

<事前> <コード> for tup in df.itertuples(): df.at[tup[0], 'rmse'] = mean_squared_error(tup[1:4], tup[4:7])**0.5

そしてそれは所望の結果を与える:

<事前> <コード> col a b c d e y rmse row a 0.00 -0.80 -0.60 -0.30 0.80 0.01 1.003677 b -0.80 0.00 0.50 0.70 -0.90 0.01 1.048825 c -0.60 0.50 0.00 0.30 0.10 0.01 0.568653 d -0.30 0.70 0.30 0.00 0.20 0.01 0.375988 e 0.80 -0.90 0.10 0.20 0.00 0.01 0.626658 y 0.01 0.01 0.01 0.01 0.01 0.00 0.005774

しかし、私のデータフレームの形状(180000000,52)があるため、ベクトル化を使用して、高性能なソリューションが必要です。列名ではなくタプルポジションによる索引付けも嫌いです。以下の試み:

<事前> <コード> df['rmse'] = df.apply(mean_squared_error(df[['a','b','c']], df[['d','e','y']])**0.5, axis=1)

エラーを取得します:

<事前> <コード> TypeError: ("'numpy.float64' object is not callable", 'occurred at index a')

だから私は私の df.apply() の使い方に何をしていますか?これは反復上のパフォーマンスを最大化しても?

テスト性能

以下のテストDFを使用して、最初の2つの対応者のそれぞれの壁掛け時間をテストしました:

<事前> <コード> # set up test df dim_x, dim_y = 50, 1000000 cols = ["a_"+str(i) for i in range(1,(dim_x//2)+1)] cols_b = ["b_"+str(i) for i in range(1,(dim_x//2)+1)] cols.extend(cols_b) shuffle(cols) df = pd.DataFrame(np.random.uniform(0,10,[dim_y, dim_x]), columns=cols) #, index=idx, columns=cols a = df.values # define column samples def column_index(df, query_cols): cols = df.columns.values sidx = np.argsort(cols) return sidx[np.searchsorted(cols,query_cols,sorter=sidx)] c0 = [s for s in cols if "a" in s] c1 = [s for s in cols if "b" in s] s0 = a[:,column_index(df, c0)] s1 = a[:,column_index(df, c1)]

結果は以下の通りである:

<事前> <コード> %%time # approach 1 - divakar rmse_out = np.sqrt(((s0 - s1)**2).mean(1)) df['rmse_out'] = rmse_out Wall time: 393 ms %%time # approach 2 - divakar diffs = s0 - s1 rmse_out = np.sqrt(np.einsum('ij,ij->i',diffs,diffs)/3.0) df['rmse_out'] = rmse_out Wall time: 228 ms %%time # approach 3 - divakar diffs = s0 - s1 rmse_out = np.sqrt((np.einsum('ij,ij->i',s0,s0) + np.einsum('ij,ij->i',s1,s1) - 2*np.einsum('ij,ij->i',s0,s1))/3.0) df['rmse_out'] = rmse_out Wall time: 421 ms

適用関数を使用した解決策は数​​分後に起動しています...

英語

Given a pandas DataFrame as below:

import pandas as pd from sklearn.metrics import mean_squared_error      df = pd.DataFrame.from_dict(            {'row': ['a','b','c','d','e','y'],             'a': [ 0, -.8,-.6,-.3, .8, .01],             'b': [-.8,  0, .5, .7,-.9, .01],             'c': [-.6, .5,  0, .3, .1, .01],             'd': [-.3, .7, .3,  0, .2, .01],             'e': [ .8,-.9, .1, .2,  0, .01],             'y': [ .01, .01, .01, .01,  .01, 0],        }).set_index('row') df.columns.names = ['col'] 

I want to create a new column of RMSE values (from scikit-learn) using specific columns for the arguments. Namely, the columns y_true = df['a','b','c'] vs y_pred = df['x','y','x']. This was easy to do using an iterative approach:

for tup in df.itertuples():     df.at[tup[0], 'rmse']  = mean_squared_error(tup[1:4], tup[4:7])**0.5 

And that gives the desired result:

col     a     b     c     d     e     y      rmse row                                               a    0.00 -0.80 -0.60 -0.30  0.80  0.01  1.003677 b   -0.80  0.00  0.50  0.70 -0.90  0.01  1.048825 c   -0.60  0.50  0.00  0.30  0.10  0.01  0.568653 d   -0.30  0.70  0.30  0.00  0.20  0.01  0.375988 e    0.80 -0.90  0.10  0.20  0.00  0.01  0.626658 y    0.01  0.01  0.01  0.01  0.01  0.00  0.005774 

But I want a higher-performance solution, possibly using vectorization, since my dataframe has shape (180000000, 52). I also dislike indexing by tuple position rather than by column name. The attempt below:

df['rmse'] = df.apply(mean_squared_error(df[['a','b','c']], df[['d','e','y']])**0.5, axis=1) 

Gets the error:

TypeError: ("'numpy.float64' object is not callable", 'occurred at index a') 

So what am I doing wrong with my use of df.apply()? Does this even maximize performance over iteration?

Testing Performance

I've tested the wall times for each of the first two respondants using the below test df:

# set up test df dim_x, dim_y = 50, 1000000 cols = ["a_"+str(i) for i in range(1,(dim_x//2)+1)] cols_b = ["b_"+str(i) for i in range(1,(dim_x//2)+1)] cols.extend(cols_b) shuffle(cols) df = pd.DataFrame(np.random.uniform(0,10,[dim_y, dim_x]), columns=cols)  #, index=idx, columns=cols a = df.values  # define column samples def column_index(df, query_cols):     cols = df.columns.values     sidx = np.argsort(cols)     return sidx[np.searchsorted(cols,query_cols,sorter=sidx)]  c0 = [s for s in cols if "a" in s] c1 = [s for s in cols if "b" in s] s0 = a[:,column_index(df, c0)] s1 = a[:,column_index(df, c1)] 

The results are as follows:

%%time # approach 1 - divakar rmse_out = np.sqrt(((s0 - s1)**2).mean(1)) df['rmse_out'] = rmse_out  Wall time: 393 ms  %%time # approach 2 - divakar diffs = s0 - s1 rmse_out = np.sqrt(np.einsum('ij,ij->i',diffs,diffs)/3.0) df['rmse_out'] = rmse_out  Wall time: 228 ms  %%time # approach 3 - divakar diffs = s0 - s1 rmse_out = np.sqrt((np.einsum('ij,ij->i',s0,s0) +           np.einsum('ij,ij->i',s1,s1) -         2*np.einsum('ij,ij->i',s0,s1))/3.0) df['rmse_out'] = rmse_out  Wall time: 421 ms 

The solution using the apply function is still running after several minutes...

</div
           

回答リスト

2
 
vote
vote
ベストアンサー
 

アプローチ#1

パフォーマンスの1つのアプローチは、これらの2つの列をスライスしてこれらのUFUNCをベクトル化された方法でスライスすることで、その2つのブロックをスライスすることで、その2つのブロックをスライスすることです。 <事前> <コード> a = df.values rmse_out = np.sqrt(((a[:,0:3] - a[:,3:6])**2).mean(1)) df['rmse_out'] = rmse_out

アプローチ#2

np.einsum

を置き換える np.einsum でRMSE値を計算するための代替方法 <事前> <コード> diffs = a[:,0:3] - a[:,3:6] rmse_out = np.sqrt(np.einsum('ij,ij->i',diffs,diffs)/3.0)

アプローチ#3

式を使用して rmse_out を計算するもう1つの方法:

(a - b)^ 2 = a ^ 2 + b ^ 2 - 2 - 2ab

スライスを抽出することです:

<事前> <コード> s0 = a[:,0:3] s1 = a[:,3:6]

その後、<コード> rmse_out は -

です。 <事前> <コード> np.sqrt(((s0**2).sum(1) + (s1**2).sum(1) - (2*s0*s1).sum(1))/3.0) einsum が付いている

<事前> <コード> np.sqrt((np.einsum('ij,ij->i',s0,s0) + np.einsum('ij,ij->i',s1,s1) - 2*np.einsum('ij,ij->i',s0,s1))/3.0)

それぞれの列インデックスを得る

99887776610 がその順番であるかどうかわからない場合は、 <コード> np.einsum1 。

このように np.einsum2 は、 np.einsum3

によって<コード> np.einsum3 np.einsum4 に置き換えられます。

 

Approach #1

One approach for performance would be to use the underlying array data alongwith NumPy ufuncs, alongwith slicing those two blocks of columns to use those ufuncs in a vectorized manner, like so -

a = df.values rmse_out = np.sqrt(((a[:,0:3] - a[:,3:6])**2).mean(1)) df['rmse_out'] = rmse_out 

Approach #2

Alternative faster way to compute the RMSE values with np.einsum to replace the squared-summation -

diffs = a[:,0:3] - a[:,3:6] rmse_out = np.sqrt(np.einsum('ij,ij->i',diffs,diffs)/3.0) 

Approach #3

Another way to compute rmse_out using the formula :

(a - b)^2 = a^2 + b^2 - 2ab

would be to extract the slices :

s0 = a[:,0:3] s1 = a[:,3:6] 

Then, rmse_out would be -

np.sqrt(((s0**2).sum(1) + (s1**2).sum(1) - (2*s0*s1).sum(1))/3.0) 

which with einsum becomes -

np.sqrt((np.einsum('ij,ij->i',s0,s0) +           np.einsum('ij,ij->i',s1,s1) -         2*np.einsum('ij,ij->i',s0,s1))/3.0) 

Getting respective column indices

If you are not sure whether the columns a,b,.. would be in that order or not, we could find those indices with column_index.

Thus a[:,0:3] would be replaced by a[:,column_index(df, ['a','b','c'])] and a[:,3:6] by a[:,column_index(df, ['d','e','y'])].

</div
 
 
         
         
2
 
vote

DF.Applyアプローチ:

<事前> <コード> rmse_out16
 

The df.apply approach:

df['rmse'] = df.apply(lambda x: mean_squared_error(x[['a','b','c']], x[['d','e','y']])**0.5, axis=1)  col     a     b     c     d     e     y      rmse row                                               a    0.00 -0.80 -0.60 -0.30  0.80  0.01  1.003677 b   -0.80  0.00  0.50  0.70 -0.90  0.01  1.048825 c   -0.60  0.50  0.00  0.30  0.10  0.01  0.568653 d   -0.30  0.70  0.30  0.00  0.20  0.01  0.375988 e    0.80 -0.90  0.10  0.20  0.00  0.01  0.626658 y    0.01  0.01  0.01  0.01  0.01  0.00  0.005774 
</div
 
 

関連する質問

1  Python - クラスタプロットチャートからリストを取得する方法  ( Python how to get list from cluster plot chart ) 
k平均クラスタリング法を使用するためにSklearnを使用しています。しかし、問題は、クラスタプロットチャートからリストを取得できます。私のコードは以下のようなです <事前> <コード> coord.service5 実際に私はすでにコードを手に入れ...

3  CATACORICALと見なす必要がある文字列を使用したSKLEARN DecisionTreeCassifier  ( Sklearn decisiontreeclassifier using strings that should be considered categoric ) 
<コード> sklearn.tree.DecisionTreeClassifier を訓練しています。 pandas.core.frame.DataFrame で始まります。このデータフレームの列の一部は、実際にカテゴリカルにする必要がある文字列です。たと...

2  XGBoost Pythonのテストデータの予測中にエラーが発生しました  ( Error while predicting test data in xgboost python ) 
XGBoost Pythonを使用してテキストの分類を実行しています 下記は私が検討しているTrainesetです。 <事前> <コード> itemid description ...

8  scikit-learn roc_auc_score()は正確さの値を返します  ( Scikit learn roc auc score returns accuracy values ) 
次の方法を使用して、<コード> sklearn.metrics.roc_auc_score を使用してROC曲線の下の領域を計算しようとしています。 <事前> <コード> roc_auc = sklearn.metrics.roc_auc_score(actu...

4  Scikit - OpenMP libsvmを学びました  ( Scikit learn openmp libsvm ) 
Scikit-Learn SVCを使用してデータを分類しています。トレーニングパフォーマンスを向上させたいのですが。 clf = svm.svc(cache_size = 4000、確率= true、verbose = true) libsvmとli...

0  Pipeline + StandardScaler + OHE + CLF + GRIDSearchCV + ColumnTranFormer  ( Pipeline standardscaler ohe clf gridsearchcv columntranformer ) 
私のLILプロジェクトのためのPipeline + StandardScaler + OHE + CLF + GRIDSearchCV + ColumnTranFormerを使用してデータモデリングしようとしていました。 私はコードを除いてちょうど罰金を尽くす...

2  ターミナルで動作していても、インポート中のPycharmエラー  ( Pycharm error while importing even though it works in the terminal ) 
パッケージTensorflowとScikit_Learnとそのすべての依存関係をインストールしました。 Python 2.7.6または2.7.10(両方とも試してみた)を使用してターミナルでそれらをインポートしてみるとうまく機能します。ただし、Pycharmを...

4  Sklearnのロジスティック回帰機能  ( Logistic regression function on sklearn ) 
Sklearnからロジスティック回帰を学んで、これに渡って来ました: http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.logisticRegression.htmor...

0  AttributeError: 'GaussianMixture'オブジェクトにはPythonに属性 'covars_'がありません  ( Attributeerror gaussianmixture object has no attribute covars in python ) 
これはこの link と下記に示すように、 <事前> <コード> from matplotlib.patches import Ellipse def draw_ellipse(position, covariance, ax=None, **kwargs...

1  カテゴリカルフィーチャカテゴリ特徴と非カテゴリカルフィーチャに回帰する方法  ( How to make regression with categorical and non categorical features ) 
複数の機能がある場合は、Sklearnで回帰をする正しい方法は何がありますが、いくつかの機能はカテゴリカーであり、いくつかは何ですか? 私は 'columntransformer'を試していましたが、私がそれをやっているのはよくわからない: <事前> <コード...




© 2022 cndgn.com All Rights Reserved. Q&Aハウス 全著作権所有