回答編集履歴

1

いろんなコードを試行してみました

2020/02/20 04:36

投稿

kirara0048
kirara0048

スコア1399

test CHANGED
@@ -1,6 +1,10 @@
1
+ その1:質問のコードを直したもの
2
+
3
+
4
+
1
- ```python
5
+ ```python
2
-
6
+
3
- df['Season'].astype(str).str.cat([
7
+ df["ID"] = df['Season'].astype(str).str.cat([
4
8
 
5
9
  df[['WTeamID', 'LTeamID']].min(1).astype(str),
6
10
 
@@ -10,7 +14,39 @@
10
14
 
11
15
 
12
16
 
17
+ その2:より簡単なコード
18
+
19
+
20
+
21
+ ```python
22
+
23
+ df["ID"] = df['Season'].astype(str).str.cat(
24
+
25
+ np.sort(df[['LTeamID', 'WTeamID']].to_numpy()).astype(str), '_')
26
+
27
+ ```
28
+
29
+
30
+
31
+ その3:リストを使う方法
32
+
33
+
34
+
35
+ ```python
36
+
37
+ arr_s = df['Season'].tolist()
38
+
39
+ arr_lw = np.sort(df[['LTeamID', 'WTeamID']].to_numpy()).tolist()
40
+
41
+ df["ID"] = pd.Series([f'{s}_{lw[0]}_{lw[1]}' for s, lw in zip(arr_s, arr_lw)],
42
+
43
+ index=df.index)
44
+
45
+ ```
46
+
47
+
48
+
13
- ## 解説
49
+ ## 解説(その1)
14
50
 
15
51
 
16
52
 
@@ -176,13 +212,13 @@
176
212
 
177
213
  ```python
178
214
 
179
- In [28]: df['Season'].astype(str).str.cat([
215
+ In [26]: df['Season'].astype(str).str.cat([
180
216
 
181
217
  2 df[['WTeamID', 'LTeamID']].min(1).astype(str),
182
218
 
183
219
  3 df[['WTeamID', 'LTeamID']].max(1).astype(str)], '_')
184
220
 
185
- Out[28]:
221
+ Out[26]:
186
222
 
187
223
  1916 2015_1214_1264
188
224
 
@@ -209,3 +245,161 @@
209
245
  Name: Season, dtype: object
210
246
 
211
247
  ```
248
+
249
+
250
+
251
+ ## 解説(その2)
252
+
253
+
254
+
255
+ 今回の場合、数値を比較して「小さい方_大きい方」という部分がありますが、この部分は`np.sort()`を使うって行ごとに「小さい→大きい」順に並べ替えした配列を作るのが簡便です。
256
+
257
+ つまり、
258
+
259
+
260
+
261
+ ```python
262
+
263
+ In [5]: arr = np.sort(df[['LTeamID', 'WTeamID']].to_numpy())
264
+
265
+ 2 arr
266
+
267
+ Out[5]:
268
+
269
+ array([[1214, 1264],
270
+
271
+ [1140, 1279],
272
+
273
+ [1129, 1173],
274
+
275
+ [1316, 1352],
276
+
277
+ [1112, 1411],
278
+
279
+ ... ...
280
+
281
+ [1181, 1211],
282
+
283
+ [1257, 1277],
284
+
285
+ [1181, 1277],
286
+
287
+ [1246, 1458],
288
+
289
+ [1181, 1458]], dtype=int64)
290
+
291
+
292
+
293
+ In [6]: df['Season'].astype(str).str.cat(arr.astype(str), '_')
294
+
295
+ Out[6]:
296
+
297
+ 1916 2015_1214_1264
298
+
299
+ 1917 2015_1140_1279
300
+
301
+ 1918 2015_1129_1173
302
+
303
+ 1919 2015_1316_1352
304
+
305
+ 1920 2015_1112_1411
306
+
307
+ ... ...
308
+
309
+ 1978 2015_1181_1211
310
+
311
+ 1979 2015_1257_1277
312
+
313
+ 1980 2015_1181_1277
314
+
315
+ 1981 2015_1246_1458
316
+
317
+ 1982 2015_1181_1458
318
+
319
+ Name: Season, dtype: object
320
+
321
+ ```
322
+
323
+
324
+
325
+ ## 解説(その3)
326
+
327
+
328
+
329
+ pandasの`str`関連メソッドは実際にはとても動作が遅いです。標準のリストになおしてforループした方が速い場合があります。
330
+
331
+
332
+
333
+ ```python
334
+
335
+ In [11]: arr_s = df['Season'].tolist()
336
+
337
+ 2 arr_lw = np.sort(df[['LTeamID', 'WTeamID']].to_numpy()).tolist()
338
+
339
+ 3 id_list = [f'{s}_{lw[0]}_{lw[1]}' for s, lw in zip(arr_s, arr_lw)]
340
+
341
+ 4 id_list
342
+
343
+ Out[11]:
344
+
345
+ ['2015_1214_1264',
346
+
347
+ '2015_1140_1279',
348
+
349
+ '2015_1129_1173',
350
+
351
+ '2015_1316_1352',
352
+
353
+ '2015_1112_1411',
354
+
355
+ '2015_1181_1211',
356
+
357
+ '2015_1257_1277',
358
+
359
+ '2015_1181_1277',
360
+
361
+ '2015_1246_1458',
362
+
363
+ '2015_1181_1458']
364
+
365
+
366
+
367
+ In [12]: pd.Series(id_list, index=df.index)
368
+
369
+ Out[12]:
370
+
371
+ 1916 2015_1214_1264
372
+
373
+ 1917 2015_1140_1279
374
+
375
+ 1918 2015_1129_1173
376
+
377
+ 1919 2015_1316_1352
378
+
379
+ 1920 2015_1112_1411
380
+
381
+ 1978 2015_1181_1211
382
+
383
+ 1979 2015_1257_1277
384
+
385
+ 1980 2015_1181_1277
386
+
387
+ 1981 2015_1246_1458
388
+
389
+ 1982 2015_1181_1458
390
+
391
+ dtype: object
392
+
393
+ ```
394
+
395
+
396
+
397
+ ## 処理速度の比較
398
+
399
+
400
+
401
+ ![処理速度の比較](5661b66313ff2c73cf29f9e52b76e9e4.png)
402
+
403
+
404
+
405
+ その3(リストを使う方法)が最も速いようです。@can110氏の方法(`df.apply`を使った方法)はデータ数が少ないときは次いで速いですが、行数が増えるとかなり遅くなります。