2017-04-14 7 views
2

私はのようなパンダのデータフレームを持っている:パンダ/ナンシー:はしごを作る最速の方法は?

color  cost temp 
0 blue  12.0 80.4 
1 red  8.1 81.2 
2 pink  24.5 83.5 

と、私は現在のコスト以下の$ 0.50〜上記の$ 0.50、「はしご」または50セント単位で行ごとの費用の「範囲」を作成したいです現在のコスト。私の現在のコードは以下のようになります。

incremented_prices = [] 

df['original_idx'] = df.index # To know it's original label 

for row in df.iterrows(): 
    current_price = row['cost'] 
    more_costs = numpy.arange(current_price-1, current_price+1, step=0.5) 

    for cost in more_costs: 
     row_c = row.copy() 
     row_c['cost'] = cost 
     incremented_prices.append(row_c) 

df_incremented = pandas.concat(incremented_prices) 

そして、このコードのようなデータフレームを生成します:本当の問題で

color  cost temp original_idx 
0 blue  11.5 80.4   0 
1 blue  12.0 80.4   0 
2 blue  12.5 80.4   0 
3 red  7.6 81.2   1 
4 red  8.1 81.2   1 
5 red  8.6 81.2   1 
6 pink  24.0 83.5   2 
7 pink  24.5 83.5   2 
8 pink  25.0 83.5   2 

を、私はからの範囲になります - $ 50.00 $ 50.00、私はこれを見つけます本当に遅い、いくつかの高速ベクトル化された方法はありますか?

+1

また、質問を言い換えることができ次のようにします。元のDFの各行がN回繰り返されたDFを作成するにはどうすればよいですか?その後、[この質問](http://stackoverflow.com/q/23887881/1258041)が役に立つかもしれません。 –

+0

@Levそれはその一部ですが、行ごとに、元の価格+/-一定額に基づいた別の価格が必要です。 – user1367204

答えて

2

あなたはnumpy.repeatとデータフレームを再作成しようとすることができます

cost_steps = pd.np.arange(-0.5, 0.51, 0.5) 
repeats = cost_steps.size 

pd.DataFrame(dict(
    color = pd.np.repeat(df.color.values, repeats), 
    # here is a vectorized method to calculate the costs with all steps added with broadcasting 
    cost = (df.cost.values[:, None] + cost_steps).ravel(), 
    temp = pd.np.repeat(df.temp.values, repeats), 
    original_idx = pd.np.repeat(df.index.values, repeats) 
    )) 

enter image description here

更新複数の列のために:

df1 = df.rename_axis("original_idx").reset_index() 
cost_steps = pd.np.arange(-0.5, 0.51, 0.5) 
repeats = cost_steps.size 

pd.DataFrame(pd.np.hstack((pd.np.repeat(df1.drop("cost", 1).values, repeats, axis=0), 
          (df1.cost[:, None] + cost_steps).reshape(-1, 1))), 
      columns=df1.columns.drop("cost").tolist()+["cost"]) 

enter image description here

+0

これは私が欲しいものですが、私は500列のようにしていますので、各列を入力する必要はありません。あなたの答えを500列のデータフレームと組み合わせる方法はありますか? – user1367204

+1

これは美しいです、ありがとうございます。 – user1367204

1

ここでのNuですMPYの使う初期ベースのアプローチ -

increments = 0.5*np.arange(-1,2) # Edit the increments here 

names = np.append(df.columns, 'original_idx') 

M,N = df.shape 
vals = df.values 

cost_col_idx = (names == 'cost').argmax() 

n = len(increments) 
shp = (M,n,N+1) 
b = np.empty(shp,dtype=object) 
b[...,:-1] = vals[:,None] 
b[...,-1] = np.arange(M)[:,None] 
b[...,cost_col_idx] = vals[:,cost_col_idx].astype(float)[:,None] + increments 
b.shape = (-1,N+1) 
df_out = pd.DataFrame(b, columns=names) 

増分が0.5の増加と-50から+50に行くようにするには、次を使用します。

increments = 0.5*np.arange(-100,101) 

サンプル実行 -

In [200]: df 
Out[200]: 
    color cost temp newcol 
0 blue 12.0 80.4 mango 
1 red 8.1 81.2 banana 
2 pink 24.5 83.5 apple 

In [201]: df_out 
Out[201]: 
    color cost temp newcol original_idx 
0 blue 11.5 80.4 mango   0 
1 blue 12 80.4 mango   0 
2 blue 12.5 80.4 mango   0 
3 red 7.6 81.2 banana   1 
4 red 8.1 81.2 banana   1 
5 red 8.6 81.2 banana   1 
6 pink 24 83.5 apple   2 
7 pink 24.5 83.5 apple   2 
8 pink 25 83.5 apple   2 
関連する問題