2017-04-20 9 views
0

に到達するまで私はこのようなデータフレームを有する:ランダムサンプル行カラムの所望の合計が

ID key acres 
1 156 10 
2 157 60 
3 158 50 
4 159 1 
5 160 9 
6 161 110 

を、私はランダムにサンプリングされた各列から選択acresの和までの行を選択します150に達するか、または可能な限り150に近い。私は選択されているすべての行の 'ID'を保存します。

私は現在、これを行うにしようとしています:

acres = 0 
obid = [] 
while acres <= 150: 
    rows = random.sample(df.index, 1) 
    sample= df.ix[rows] 
    acres = acres + sample['acres'] 
    obid.append(sample['ID']) 
    df= df.drop(rows) 

をしかし、このアプローチにはカップルの問題があります。まず、元のdfを実際に変更するのではなく、ループ内でサンプルを削除するので、同じ行が2回サンプリングされる可能性があります。次に、このエラーが返されます。

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all(). 

これは私にはより良いアプローチがあると信じています。

+0

ランダム描画で表示されている行がすべて表示されてしまうことがあります。 'ID == 6'が最後に描画された場合は、acresの合計が240になります。これは問題ありませんか? – James

+0

はい私はそれを扱うことができます。 –

答えて

1

はのは、このような何かを試してみましょう:

  • sampleは、データフレームからのサンプル行を引っ張る、引数frac=1状態が
    行の100%を取得します。これは基本的にデータフレームをシャッフルします。

  • iterrrowsを使用して、シャッフルされたデータフレームを反復処理します。

コード:

acres = 0 
obid = [] 
for i in df.sample(frac=1).iterrows(): 
    if (acres + i[1]['acres']) <= 150: 
     acres += i[1]['acres'] 
     obid.append(i[1]['ID']) 

print(obid) 

出力:

[5, 6, 4, 1] 

の結果

print(df[df['ID'].isin(obid)]) 

出力して、元のデータフレームを見てみましょう

ID key acres 
0 1 156  10 
3 4 159  1 
4 5 160  9 
5 6 161 110