回答編集履歴

2

挿入ソート版追記

2019/02/14 02:29

投稿

can110
can110

スコア38266

test CHANGED
@@ -291,3 +291,161 @@
291
291
  """
292
292
 
293
293
  ```
294
+
295
+ 挿入ソート版
296
+
297
+ -----
298
+
299
+ 題意から以下の処理でもよさそうです。
300
+
301
+ 再帰版よりもはるかに速く処理できます。
302
+
303
+
304
+
305
+ ```Python
306
+
307
+ import numpy as np
308
+
309
+ import pprint
310
+
311
+
312
+
313
+ import pandas as pd
314
+
315
+ from io import StringIO
316
+
317
+ f = StringIO("""c1,c2,c3,c4,c5
318
+
319
+ ,,7,8,
320
+
321
+ 1,2,,,
322
+
323
+ ,,6,6,
324
+
325
+ 4,7,,,
326
+
327
+ ,,,2,1
328
+
329
+ ,,,7,4
330
+
331
+ 6,9,,,
332
+
333
+ ,1,2,,
334
+
335
+ ,,,9,5
336
+
337
+ ,4,4,,
338
+
339
+ ,,1,1,
340
+
341
+ 2,3,,,
342
+
343
+ 5,8,,,
344
+
345
+ ,,,3,2
346
+
347
+ ,,3,4,
348
+
349
+ ,5,5,,
350
+
351
+ ,,,5,3
352
+
353
+ 3,6,,,""")
354
+
355
+ ary = pd.read_csv(f).values.tolist()
356
+
357
+
358
+
359
+
360
+
361
+ ret = []
362
+
363
+
364
+
365
+ # 各列について左から順に処理
366
+
367
+ col_cnt = len(ary[0])
368
+
369
+ for c in range(col_cnt):
370
+
371
+
372
+
373
+ # 対象列がnanでない行のみ抜き出す
374
+
375
+ rows = []
376
+
377
+ for r in ary[::-1]:
378
+
379
+ if not np.isnan(r[c]):
380
+
381
+ rows.append(r)
382
+
383
+ ary.remove(r)
384
+
385
+
386
+
387
+ # 結果配列に列値が昇順になるように挿入していく
388
+
389
+ for row in rows:
390
+
391
+ is_ins = False
392
+
393
+ for idx,ret_row in enumerate(ret):
394
+
395
+ if row[c] < ret_row[c]:
396
+
397
+ ret.insert(idx,row)
398
+
399
+ is_ins = True
400
+
401
+ break
402
+
403
+ if not is_ins:
404
+
405
+ ret.append(row)
406
+
407
+
408
+
409
+ pprint.pprint(ret)
410
+
411
+ """
412
+
413
+ [[nan, nan, 1.0, 1.0, nan],
414
+
415
+ [nan, 1.0, 2.0, nan, nan],
416
+
417
+ [1.0, 2.0, nan, nan, nan],
418
+
419
+ [2.0, 3.0, nan, nan, nan],
420
+
421
+ [nan, nan, nan, 2.0, 1.0],
422
+
423
+ [nan, nan, nan, 3.0, 2.0],
424
+
425
+ [nan, nan, 3.0, 4.0, nan],
426
+
427
+ [nan, 4.0, 4.0, nan, nan],
428
+
429
+ [nan, 5.0, 5.0, nan, nan],
430
+
431
+ [3.0, 6.0, nan, nan, nan],
432
+
433
+ [4.0, 7.0, nan, nan, nan],
434
+
435
+ [5.0, 8.0, nan, nan, nan],
436
+
437
+ [6.0, 9.0, nan, nan, nan],
438
+
439
+ [nan, nan, nan, 5.0, 3.0],
440
+
441
+ [nan, nan, 6.0, 6.0, nan],
442
+
443
+ [nan, nan, nan, 7.0, 4.0],
444
+
445
+ [nan, nan, 7.0, 8.0, nan],
446
+
447
+ [nan, nan, nan, 9.0, 5.0]]
448
+
449
+ """
450
+
451
+ ```

1

再帰版を追記

2019/02/14 02:29

投稿

can110
can110

スコア38266

test CHANGED
@@ -117,3 +117,177 @@
117
117
  """
118
118
 
119
119
  ```
120
+
121
+
122
+
123
+
124
+
125
+ 再帰版
126
+
127
+ -----
128
+
129
+
130
+
131
+ 総当たりよりは速いですが、15行程度が限界ですね。
132
+
133
+ ```Python
134
+
135
+
136
+
137
+ import numpy as np
138
+
139
+
140
+
141
+ def search( ary):
142
+
143
+ row_cnt = ary.shape[0]
144
+
145
+ col_cnt = ary.shape[1]
146
+
147
+
148
+
149
+ # 条件を満たすか
150
+
151
+ # row : 行の位置
152
+
153
+ # mins : 現時点の各列の最小値
154
+
155
+ def is_match(row,mins):
156
+
157
+ for col in range(col_cnt):
158
+
159
+ v = ary[row,col]
160
+
161
+ if np.isnan(v):
162
+
163
+ continue
164
+
165
+ if v < mins[col]:
166
+
167
+ return False
168
+
169
+ mins[col] = v # 最小値を更新
170
+
171
+ return True
172
+
173
+
174
+
175
+ # rows : 行位置の配列
176
+
177
+ # mins : 現時点の各列の最小値
178
+
179
+ def search_row(rows,mins):
180
+
181
+ if len(rows) == row_cnt:
182
+
183
+ return rows
184
+
185
+
186
+
187
+ rows_set = set(rows)
188
+
189
+ for row in range(row_cnt):
190
+
191
+ if row in rows_set: # 重複は除く
192
+
193
+ continue
194
+
195
+ next_mins = mins.copy()
196
+
197
+ if is_match(row,next_mins):
198
+
199
+ ret = search_row(rows+[row],next_mins)
200
+
201
+ if ret:
202
+
203
+ return ret
204
+
205
+
206
+
207
+ rows = search_row([],np.zeros(col_cnt))
208
+
209
+ return ary[rows,:]
210
+
211
+
212
+
213
+
214
+
215
+ import pandas as pd
216
+
217
+ from io import StringIO
218
+
219
+ f = StringIO("""c1,c2,c3,c4,c5
220
+
221
+ ,,7,8,
222
+
223
+ 1,2,,,
224
+
225
+ ,,6,6,
226
+
227
+ 4,7,,,
228
+
229
+ ,,,2,1
230
+
231
+ ,,,7,4
232
+
233
+ ,1,2,,
234
+
235
+ ,4,4,,
236
+
237
+ ,,1,1,
238
+
239
+ 2,3,,,
240
+
241
+ ,,,3,2
242
+
243
+ ,,3,4,
244
+
245
+ ,5,5,,
246
+
247
+ ,,,5,3
248
+
249
+ 3,6,,,""")
250
+
251
+ ary = pd.read_csv(f).values
252
+
253
+
254
+
255
+ ret = search(ary)
256
+
257
+ print(ret)
258
+
259
+ """
260
+
261
+ [[nan nan 1. 1. nan]
262
+
263
+ [nan nan nan 2. 1.]
264
+
265
+ [nan 1. 2. nan nan]
266
+
267
+ [ 1. 2. nan nan nan]
268
+
269
+ [ 2. 3. nan nan nan]
270
+
271
+ [nan nan nan 3. 2.]
272
+
273
+ [nan nan 3. 4. nan]
274
+
275
+ [nan 4. 4. nan nan]
276
+
277
+ [nan 5. 5. nan nan]
278
+
279
+ [nan nan nan 5. 3.]
280
+
281
+ [nan nan 6. 6. nan]
282
+
283
+ [nan nan nan 7. 4.]
284
+
285
+ [nan nan 7. 8. nan]
286
+
287
+ [ 3. 6. nan nan nan]
288
+
289
+ [ 4. 7. nan nan nan]]
290
+
291
+ """
292
+
293
+ ```