Сегодня хочу рассмотреть вопрос тестирования и корректной выборки данных в тестах приложений, а именно, как сделать выборку с точным процентом строк. Например, у меня есть 10 000 строк, и я хочу получить в выборке 10%, а не 1043 или 958. Вот об этом и расскажу далее.
Результаты теста
В таблицах ниже представлена выборка тестирования с традиционным кодом и новым подходом к выборке. Результаты представлены из фиксированного набора данных из 2 млн. строк:
Результаты из случайного количества строк из набора данных:
Результаты для меньшего количества случайных строк из набора данных:
Здесь привожу контрольную выборку, чтобы показать, что в каждом случае использовались разные строки:
Типичный подход
Общепринятое правило – использование такого кода, который может быть запущен сразу внутри таблицы, если вам нужны отдельные выборки строк. Также вы можете создать таблицу мэппинга или использовать Left Join, если хотите сделать выборку измерения.
Код, который будем использовать в этом случае:
if((rand()<=0.10+now()*0) = 0, ‘Standard Group’, ‘Trial Group’), где 0.10 — это 10% выборки. Теперь оно будет варьироваться в пределах от +/- 1%, что подходит в моем случае в решении большинства задач тестирования, но нам важно, чтобы можно было выбрать конкретный процент.
Как использовать этот код: для выборки всех строк
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
//random row sampler Transactions: load rowno() as ID,//уникальный идентификатор строки if((rand()<=0.10+now()*0) = 0, 'Standard Group', 'Trial Group') as trial_flag, '1' as TransCounter, TransLineID, TransID, Pick(Ceil(5*Rand1),'A','B','C','D','E') as Department, money(round(RAND()*25000,0.01)) AS Value; Load Rand() as Rand1, floor(rand()*100) as TransLineID, floor(rand()*100000) as TransID Autogenerate 10000*Rand() While Rand()<=0.5 or IterNo()=1; Для выборки измерения: //случайная выборка измерения Transactions: load rowno() as ID,// уникальный идентификатор строки '1' as TransCounter, TransLineID, TransID, Pick(Ceil(5*Rand1),'A','B','C','D','E') as Department, money(round(RAND()*25000,0.01)) AS Value; Load Rand() as Rand1, floor(rand()*100) as TransLineID, floor(rand()*100000) as TransID Autogenerate 10000*Rand() While Rand()<=0.5 or IterNo()=1; NoConcatenate tmp: load distinct TransID Resident Transactions; NoConcatenate tmp2: load TransID, if((rand()<=0.10+now()*0) = 0, 'Standard Group', 'Trial Group') as trial_flag resident tmp; drop table tmp; left join (Transactions) load TransID, trial_flag resident tmp2; drop table tmp2; |
Мое решение
Мое решение этой задачи несколько более длинное, включает загрузки и преобразования данных из ранее загруженной таблицы и их объединения. В итоге, обработка набора данных в 2 млн. строк заняла у меня всего 10 секунд, хотя для решения этой задачи определенно есть более быстрые решения.
Для упрощения всего процесса я добавил несколько переменных.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 |
//определение переменных //изменения нужно внести здесь, чтобы все соответствовало вашим требованиям let v_sample_size = 0.05; // 5% let v_sample_type = 'column'; //здесь может быть таблица или колонка. Если ничего не указано, то выборка производиться не будет let v_sample_table = 'Transactions'; let v_sample_column = 'TransID'; let v_sort_order = if(rand() >=0.5,'desc','asc'); let v_sample_column_name ='Trial Flag'; let v_sample_column_true='Trial Group'; let v_sample_column_false='Standard Group'; //загружаем какие-то данные //********************************************************************************************************** // вставляем сюда свой код //********************************************************************************************************** //создаем QVD, если его еще нет Transactions: load rowno() as ID,//ID строки '1' as TransCounter, TransLineID, TransID, Pick(Ceil(5*Rand1),'A','B','C','D','E') as Department, money(round(RAND()*25000,0.01)) AS Value; Load Rand() as Rand1, floor(rand()*100) as TransLineID, floor(rand()*100000) as TransID Autogenerate 10000*Rand() While Rand()<=0.5 or IterNo()=1;; //********************************************************************************************************** //********************************************************************************************************** //здесь работает выборки //выборки колонок if v_sample_type='column' THEN //load the distinct column value testtable: load distinct $(v_sample_column) Resident $(v_sample_table); left join (testtable) LOAD $(v_sample_column),num(rand(),'0.00000000')as xx_randomnumber resident testtable; let v_load_number = round(NoOfRows('testtable')*$(v_sample_size)); NoConcatenate sampleoutputtable: first $(v_load_number) load $(v_sample_column), '$(v_sample_column_true)' as xx_flag Resident testtable order by xx_randomnumber $(v_sort_order); drop table testtable; left join ($(v_sample_table)) load $(v_sample_column), xx_flag resident sampleoutputtable; join ($(v_sample_table)) load $(v_sample_column), if(len(trim(xx_flag))>0,xx_flag,'$(v_sample_column_false)') as [$(v_sample_column_name)] resident $(v_sample_table); drop table sampleoutputtable; drop field xx_flag; end if if v_sample_type='table' THEN testtable: LOAD $(v_sample_column),num(rand(),'0.00000000')as xx_randomnumber Resident $(v_sample_table); let v_load_number = round(NoOfRows('testtable')*$(v_sample_size)); NoConcatenate sampleoutputtable: first $(v_load_number) load $(v_sample_column), '$(v_sample_column_true)' as xx_flag Resident testtable order by xx_randomnumber $(v_sort_order); drop table testtable; left join ($(v_sample_table)) load $(v_sample_column), xx_flag resident sampleoutputtable; join ($(v_sample_table)) load $(v_sample_column), if(len(trim(xx_flag))>0,xx_flag,'$(v_sample_column_false)') as [$(v_sample_column_name)] resident $(v_sample_table); drop table sampleoutputtable; drop field xx_flag; end if |
Файлы примеров:
На этом все на сегодня! Отличных вам разработок с Qlik!
Свежие комментарии