線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:3298
推到 Plurk!
推到 Facebook!

抽樣的問題

答題得分者是:jow
joanne1250
一般會員


發表:3
回覆:6
積分:1
註冊:2007-11-19

發送簡訊給我
#1 引用回覆 回覆 發表時間:2007-11-30 14:55:06 IP:61.231.xxx.xxx 訂閱
請問各位前輩如何在限制範圍內進行抽樣?
Ex.至少30筆資料,每3筆抽一個樣品出來

我有先搜尋過有關抽樣等資料
但只有一些有關亂數隨機抽樣的資訊
請問我該從哪個方向著手?或是給一些提示^^
jow
尊榮會員


發表:66
回覆:751
積分:1253
註冊:2002-03-13

發送簡訊給我
#2 引用回覆 回覆 發表時間:2007-11-30 15:52:34 IP:210.66.xxx.xxx 訂閱
程式碼供你參考...........

[code cpp]
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
Randomize();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
DynamicArray A;
int RandomRange = 1000; //亂數值範圍
int SampleCount = 30 random(100);//最少30筆
A.set_length(SampleCount);
try{
int i = 0;
int k = 0;
do{
int r = random(RandomRange);
if(i %3 == 0) A[k ] = r;
}while(k //顯示結果
ListBox1->Clear();
for(int i=0; i ListBox1->Items->Add(IntToStr(A[i]));
ShowMessage("Count=" IntToStr(A.Length));
}
__finally{
A.set_length(0);
}
}
//---------------------------------------------------------------------------

[/code]

===================引 用 joanne1250 文 章===================
請問各位前輩如何在限制範圍內進行抽樣?
Ex.至少30筆資料,每3筆抽一個樣品出來

我有先搜尋過有關抽樣等資料
但只有一些有關亂數隨機抽樣的資訊
請問我該從哪個方向著手?或是給一些提示^^
joanne1250
一般會員


發表:3
回覆:6
積分:1
註冊:2007-11-19

發送簡訊給我
#3 引用回覆 回覆 發表時間:2007-11-30 16:26:23 IP:61.231.xxx.xxx 訂閱
我執行過前輩提供的程式碼了
不好意思> <第一次發問沒說清楚
我是已經在StringGrid中輸入30~100筆的資料
在資料中每3筆抽出1筆資料
如果說是30筆資料,總共抽出10筆資料
我還要再對這10筆資料做加總並計算
想請問的是如何抽樣跟取得抽出來的數據
再次不好意思...煩請指教^^
jow
尊榮會員


發表:66
回覆:751
積分:1253
註冊:2002-03-13

發送簡訊給我
#4 引用回覆 回覆 發表時間:2007-11-30 18:18:09 IP:123.193.xxx.xxx 訂閱
(1)修改程式碼...
(2)允許資料重複被取樣...

[code cpp]
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
Randomize();
}
//---------------------------------------------------------------------------
void __fastcall GetRandomData(DynamicArray& A)
{
int RandomRange = 1000; //亂數值範圍
int SampleCount = 30 random(71);//30~100筆資料
A.set_length(SampleCount);
int k = 0;
do{
A[k ] = random(RandomRange);
}while(k < SampleCount);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
DynamicArray A, B;
GetRandomData(A);
try{
int len = (int)A.Length / 3;
if(len > 0){
B.Length = len;
try{
int k = 0;
do{
B[k ] = A[random(A.Length)];
}while(k < len);
//顯示結果
ListBox1->Clear();
for(int i=0; i ListBox1->Items->Add(IntToStr(B[i]));
ShowMessage("Count=" IntToStr(B.Length));
}
__finally{
B.Length = 0;
}
}
}
__finally{
A.Length = 0;
}
}
//---------------------------------------------------------------------------
[/code]

===================引 用 joanne1250 文 章===================
我執行過前輩提供的程式碼了
不好意思> <第一次發問沒說清楚
我是已經在StringGrid中輸入30~100筆的資料
在資料中每3筆抽出1筆資料
如果說是30筆資料,總共抽出10筆資料
我還要再對這10筆資料做加總並計算
想請問的是如何抽樣跟取得抽出來的數據
再次不好意思...煩請指教^^
編輯記錄
jow 重新編輯於 2007-11-30 18:18:42, 註解 無‧
joanne1250
一般會員


發表:3
回覆:6
積分:1
註冊:2007-11-19

發送簡訊給我
#5 引用回覆 回覆 發表時間:2007-12-03 15:08:53 IP:61.224.xxx.xxx 訂閱
jow前輩您好
不好意思..以下是我取得檔案的程式碼

[code cpp]

void __fastcall TForm1::Button2Click(TObject *Sender)
{
int icounts=0;
int i;
double S[100]={0};

for(i=1;i<=100;i )
{
if(StringGrid1->Cells[1][i]!="")
{
icounts ;
}
}
for(i=1;i<=icounts;i ) //將SringGrid1的數值存入S[]
{
S[i] = StringGrid1->Cells[1][i].ToDouble();
}
}


[/code]
我試過將jow前輩程式碼中的DynamicArray A更換成S[icounts]
可是無法執行 ==> [C Error] Unit1.cpp(287): E2252 'catch' expected
是否能這樣更換呢?
編輯記錄
joanne1250 重新編輯於 2007-12-03 15:10:13, 註解 無‧
joanne1250 重新編輯於 2007-12-03 15:12:10, 註解 無‧
joanne1250 重新編輯於 2007-12-03 15:12:53, 註解 無‧
jow
尊榮會員


發表:66
回覆:751
積分:1253
註冊:2002-03-13

發送簡訊給我
#6 引用回覆 回覆 發表時間:2007-12-03 16:15:52 IP:210.66.xxx.xxx 訂閱
(1)StringGrid1.Cells[][]是否為空字串, 與筆數icounts在位置(Col, Row)上不是绝對從0開始
以一對一的形式對應...

(2)陣列索引值是否超出範圍(最好從0開始到Count-1)
S[100] --> S[0] ~ S[99];
StringGrid1.Cells[c][r]---> c: 0~ColCount-1, r: 0~RowCount-1

(3)執行ToDouble()之前, 是否應該先檢查Cells[][]是否為空字串?!!
這部分要試試看 TStringGrid有沒有做例外處理...

(4)資料處理在還沒有要顯示結果時, 應該盡量與UI分開處理,
除非這個畫面是作為即時資料輸出/輸入互動的...

幾點看法供你參考...


[code cpp]
void __fastcall TForm1::Button2Click(TObject *Sender)
{
int icounts=0;
double S[100];
memset(&S,0,sizeof(S));
//將SringGrid1的數值存入S[]
int rc = StringGrid1->RowCount;
for(int i=1;i if(StringGrid1->Cells[1][i]!=""&&icounts<100)
S[icounts ] = StringGrid1->Cells[1][i].ToDouble();
}

[/code]

編輯記錄
jow 重新編輯於 2007-12-03 16:25:04, 註解 無‧
jow 重新編輯於 2007-12-03 16:26:38, 註解 無‧
joanne1250
一般會員


發表:3
回覆:6
積分:1
註冊:2007-11-19

發送簡訊給我
#7 引用回覆 回覆 發表時間:2007-12-03 17:24:36 IP:61.224.xxx.xxx 訂閱
我是從Excel讀檔案到StringGrid,是屬於即時輸出/入的嗎?
先前已經將StringGrid裡的數值計算過並可以顯示
目前我的問題是還不了解該怎麼使用前輩提供參考的code
[code cpp]
try{
int len = icounts / 3;
if(len > 0)
{
A.Length = len;
try{
int g = 0;
do{
A[g ] = S[icounts]; //原先是B[k ] = A[random(A.Length)];不懂如果我第一個陣列不是DynamicArray,而是double S[icounts], 請教前輩我應該如何修正?
}while(g < len);
//顯示結果
ListBox1->Clear();
for(int h=0; h ListBox1->Items->Add(IntToStr(S[i]));
ShowMessage("Count=" IntToStr(A.Length));
}
__finally{ A.Length = 0; }
}
}
[/code]

===================引 用 jow 文 章===================
(1)StringGrid1.Cells[][]是否為空字串, 與筆數icounts在位置(Col, Row)上不是绝對從0開始
以一對一的形式對應...

(2)陣列索引值是否超出範圍(最好從0開始到Count-1)
S[100] --> S[0] ~ S[99];
StringGrid1.Cells[c][r]---> c: 0~ColCount-1, r: 0~RowCount-1

(3)執行ToDouble()之前, 是否應該先檢查Cells[][]是否為空字串?!!
這部分要試試看 TStringGrid有沒有做例外處理...

(4)資料處理在還沒有要顯示結果時, 應該盡量與UI分開處理,
除非這個畫面是作為即時資料輸出/輸入互動的...

幾點看法供你參考...


[code cpp]
void __fastcall TForm1::Button2Click(TObject *Sender)
{
int icounts=0;
double S[100];
memset(&S,0,sizeof(S));
//將SringGrid1的數值存入S[]
int rc = StringGrid1->RowCount;
for(int i=1;i if(StringGrid1->Cells[1][i]!=""&&icounts<100)
S[icounts ] = StringGrid1->Cells[1][i].ToDouble();
}

[/code]

編輯記錄
joanne1250 重新編輯於 2007-12-03 17:25:48, 註解 無‧
joanne1250 重新編輯於 2007-12-03 17:27:02, 註解 無‧
joanne1250 重新編輯於 2007-12-03 17:29:06, 註解 無‧
jow
尊榮會員


發表:66
回覆:751
積分:1253
註冊:2002-03-13

發送簡訊給我
#8 引用回覆 回覆 發表時間:2007-12-04 00:41:11 IP:123.193.xxx.xxx 訂閱

[code cpp]
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
//模擬自Excel讀入資料到StringGrid1
int rc = 101;
StringGrid1->RowCount = rc;
for(int i=1; i double d = (double)random(10000)/(10 random(90));
String S;
S.sprintf("%.3f", d);
StringGrid1->Cells[1][i] = S;
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
//(1)取樣將SringGrid1的數值存入S[]===========================================
int rc = StringGrid1->RowCount;
double *d = new double[rc]; //動態配置記憶體Buffer
try{
memset(d,0,sizeof(double)*(rc)); //將動態配置記憶體Buffer清除為零
int icounts=0;
for(int i=1; i if(StringGrid1->Cells[1][i]!=""&&icounts<100)
d[icounts ] = StringGrid1->Cells[1][i].ToDouble();
//(2)抽樣: 每3筆抽取一筆資料----------------------------------------------
int len = (int)icounts / 3;
if(len > 0){
double *dd = new double[len];/*動態配置記憶體Buffer*/
try{
memset(dd,0,sizeof(double)*(len));/*將動態配置記憶體Buffer清除為零*/
int k = 0;
do{
dd[k ] = d[random(icounts)];
}while(k < len);
//(3)顯示抽樣結果***************************************************
for(int i=0; i String S;
S.sprintf("%.3f", dd[i]);
StringGrid1->Cells[2][i 1] = S;/*從Row[1]開始,Row[0]為Fixed Row*/
}
ShowMessage("Count=" IntToStr(len));/*顯示dd資料數*/
//(3)顯示抽樣結果***************************************************
}
__finally{
delete dd;/*釋放動態配置的記憶體*/
}
}
//(2)抽樣: 每3筆抽取一筆資料----------------------------------------------
}
__finally{
delete d;/*釋放動態配置的記憶體*/
}
//(1)取樣將SringGrid1的數值存入S[]===========================================
}
//---------------------------------------------------------------------------
[/code]
joanne1250
一般會員


發表:3
回覆:6
積分:1
註冊:2007-11-19

發送簡訊給我
#9 引用回覆 回覆 發表時間:2007-12-04 16:16:09 IP:61.231.xxx.xxx 訂閱
謝謝jow前輩^^
可以執行抽樣了~
但我希望我抽出的資料不重複(ex.檔案中只有1個50,卻抽出2個50)
如果這樣計算出來的平均值就不準確了
可是在讀取的檔案中也會有重複的資料
ex.讀檔案至StringGrid的資料為
53,48,54,52,48,50,46,52,51,49 (共10筆)
其中48與52各有2筆,其餘只有各1筆資料
每3個抽1個出來==>以此例會抽出3筆資料
請教如何在抽樣出來的結果別出現類似這種情況:
{54,54,49} or {51,48,51}
但是卻可以抽出例如:{48,48,53} or {48,52,52}
jow
尊榮會員


發表:66
回覆:751
積分:1253
註冊:2002-03-13

發送簡訊給我
#10 引用回覆 回覆 發表時間:2007-12-04 16:42:37 IP:210.66.xxx.xxx 訂閱
程式重貼. . . 
[code cpp]
memset(dd,0,sizeof(double)*(len)); /*將動態配置記憶體Buffer清除為零*/
byte *ss = new byte[icounts]; /*==1, 表示該數值已被選取 */
try{
memset(ss,0,sizeof(byte)*(icounts));/*清除選取狀態*/
int k = 0, j;
do{
j = random(icounts);
if(ss[j]!=1){
dd[k] = d[j];
ss[j] = 1; /*標示已被選取*/
k ;
}
}while(k < len);
}
__finally{
delete ss;
}
[/code]
編輯記錄
jow 重新編輯於 2007-12-04 16:45:21, 註解 無‧
jow 重新編輯於 2007-12-04 16:46:41, 註解 無‧
jow 重新編輯於 2007-12-04 17:06:44, 註解 程式修正byte *ss 的配置長度應 為 icounts‧
jow 重新編輯於 2007-12-04 17:08:37, 註解 無‧
joanne1250
一般會員


發表:3
回覆:6
積分:1
註冊:2007-11-19

發送簡訊給我
#11 引用回覆 回覆 發表時間:2007-12-05 16:21:26 IP:61.217.xxx.xxx 訂閱
太感謝前輩了^^
修正以後都不會重複了~
謝謝教導~謝謝
系統時間:2024-05-07 17:26:27
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!