2016-07-13 1 views
2

私はpandasデータフレームとしてshape =(2000、200000)として大規模構造を持っています。各列の2つの値のすべてをその特定の列平均値(2つの値を除く)。これは私が小さな構造物のために行う方法ですが、大きな構造物の場合はかなり長い時間がかかります。 YはDataFrameです。列ごとに特定の値をより速く置き換える方法、Python

for i in Y.columns: 
    x = Y[i][Y[i] != 2].mean() 
    Y[i][Y[i] == 2] = x 

高速なソリューションがありますか?

答えて

1

あなたのデータフレームがdfであると仮定すると、してみましょう:

a = df.values 

私は平均が

avg = (a.sum(0) - (a == 2).sum(0) * 2.)/(a != 2).sum(0) 
と非補数を越えているものを計算したいです

(a == 2).sum(0)は、2の番号です各列のs。

np.whereを使用してaavgの間で選択してください。それをpd.DataFrameコンストラクタでラップします。

pd.DataFrame(np.where(a != 2, a, avg), df.index, df.columns) 
3

あなたは算術演算で作業しているので、私は、numpyのにすべてのそれらの計算の負荷を軽減示唆最終結果を取得し、データフレームを作成し、そのたい - さらなるパフォーマンスの向上のために

# Extract into an array 
arr = Y.values 

# Mask to set or not-set elements in array 
mask = arr!=2 

# Compute the mean vaalues for masked elements along each column 
avg = np.true_divide((arr*mask).sum(0),mask.sum(0)) 

# Finally choose values based on mask and create output dataframe 
Yout = pd.DataFrame(np.where(~mask,avg,arr),columns=Y.columns) 

、あなたはおそらく置き換えることができます(arr*mask).sum(0) np.einsum('ij,ij->j',arr,mask)np.einsumとすると、ほとんどの場合非常に効率的です。

サンプル実行して結果を確認します -

In [128]: Y = pd.DataFrame(np.random.randint(0,4,(10,5))) 

In [129]: arr = Y.values 
    ...: mask = arr!=2 
    ...: avg = np.true_divide((arr*mask).sum(0),mask.sum(0)) 
    ...: Yout = pd.DataFrame(np.where(~mask,avg,arr),columns=Y.columns) 
    ...: 

In [130]: for i in Y.columns: 
    ...:  x = Y[i][Y[i] != 2].mean() 
    ...:  Y[i][Y[i] == 2] = x 
    ...:  

In [131]: np.allclose(Y,Yout) 
Out[131]: True 
+0

両方の素晴らしい回答、ありがとうございます!私はあなたの仕事と同じように素早く仕事をしているので、piRSquaredを受け入れています。そして、彼は1時間前に質問しました(私は目が覚めていて、私はそれを受け入れました)。 – atomsmasher

関連する問題