回答編集履歴

5

回答に追記

2023/07/06 06:41

投稿

退会済みユーザー
test CHANGED
@@ -18,7 +18,7 @@
18
18
  )
19
19
  ```
20
20
 
21
- ## 追記
21
+ ## 追記1
22
22
  以下の2点
23
23
  1. DataFrame.groupby メソッドを使うこと
24
24
  2. 最終的に得たい DataFrame のカラムの並び順を質問にあるように `01_100m, 01_1000m, 02_100m, 02_1000m` とすること
@@ -36,3 +36,30 @@
36
36
 
37
37
  ![イメージ説明](https://ddjkaamml8q8x.cloudfront.net/questions/2023-07-06/8e4e323b-2224-44e0-9467-158e130798d2.png)
38
38
 
39
+ ## 追記2
40
+
41
+ `df.groupby` の第1引数には、各列名に対応するグループ化するときのキーを得る関数をそのまま渡せるので、追記1に書いた2行
42
+ ```python
43
+ cols_map = {col: get_key(col) for col in df.columns}
44
+ total_df = df.groupby(cols_map, axis=1, sort=True).sum().rename(columns=lambda col: f'{col}m')
45
+ ```
46
+ は、dict `cols_map` を作らずとも以下の1行で済むところでした。
47
+
48
+ ```python
49
+ total_df = df.groupby(get_key, axis=1, sort=True).sum().rename(columns=lambda k: f'{k}m')
50
+ ```
51
+
52
+ **備考**
53
+
54
+ さらにリファクタの思いつきですが、グループ化のキーに末尾の`'m'` を含めるか含まないかでソート結果が変わってしまうのを気にしたコードを書くのはやや煩雑なので
55
+
56
+ - `get_key`関数は `'01男性_有効_有効_100m'` に対して `('01', 100)` というタプルを返させるようにして、
57
+
58
+ - 集計したDataFrameの列を rename するときの columns に、このタプルから `'01_100m'` を返すlambdaを指定する
59
+
60
+ というのもアリかなと思いました。
61
+
62
+
63
+
64
+
65
+

4

回答に追記

2023/07/06 05:07

投稿

退会済みユーザー
test CHANGED
@@ -18,3 +18,21 @@
18
18
  )
19
19
  ```
20
20
 
21
+ ## 追記
22
+ 以下の2点
23
+ 1. DataFrame.groupby メソッドを使うこと
24
+ 2. 最終的に得たい DataFrame のカラムの並び順を質問にあるように `01_100m, 01_1000m, 02_100m, 02_1000m` とすること
25
+
26
+ が求められているのであれば、下記のようにします。(`get_key`関数は先述したものをそのまま使います)
27
+
28
+ ```python
29
+ cols_map = {col: get_key(col) for col in df.columns}
30
+ total_df = df.groupby(cols_map, axis=1, sort=True).sum().rename(columns=lambda col: f'{col}m')
31
+ ```
32
+
33
+ 上記のように`df.groupby` のキーワード引数 `sort` にTrueを指定しますが、このときに 上記の 2. のような列の並びを得るためには、`get_key`関数で得られる各列名のキーには末尾の`m` を含めないようにしておく必要があります。そのため集計してから、あらためて各列の末尾に `m` を付加しています。
34
+
35
+ **上記の実行例:**
36
+
37
+ ![イメージ説明](https://ddjkaamml8q8x.cloudfront.net/questions/2023-07-06/8e4e323b-2224-44e0-9467-158e130798d2.png)
38
+

3

回答プログラム修正

2023/07/05 23:18

投稿

退会済みユーザー
test CHANGED
@@ -5,7 +5,7 @@
5
5
  import re
6
6
 
7
7
  def get_key(x):
8
- return re.sub(r'^(\d{2})[^\d]+(\d+)m$', r'\1-\2', x)
8
+ return re.sub(r'^(\d{2})[^\d]+(\d+)m$', r'\1_\2', x)
9
9
  ```
10
10
  この `get_key(x)` を使って列をグループ化し、同じキーとなる列を合計したSeriesを各列とするDataFarame `total_df` を作るには以下のようにします。
11
11
 

2

回答プログラム修正

2023/07/05 23:08

投稿

退会済みユーザー
test CHANGED
@@ -5,7 +5,7 @@
5
5
  import re
6
6
 
7
7
  def get_key(x):
8
- return re.sub(r'^(\d{2})[^0-9]+(\d+)m$', r'\1-\2', x)
8
+ return re.sub(r'^(\d{2})[^\d]+(\d+)m$', r'\1-\2', x)
9
9
  ```
10
10
  この `get_key(x)` を使って列をグループ化し、同じキーとなる列を合計したSeriesを各列とするDataFarame `total_df` を作るには以下のようにします。
11
11
 

1

回答テキスト修正

2023/07/05 23:06

投稿

退会済みユーザー
test CHANGED
@@ -1,6 +1,6 @@
1
1
  元データから作ったDataFrame を `df` とします。(ただし`UID` は`df`のインデクスに使用するものとします。)
2
2
 
3
- まず、`'01男性_有効_有効_100m'` という文字列から `'01_100m'` という文字列を得る関数を作っておきます。
3
+ まず、`'01男性_有効_有効_100m'` という文字列から ~~`'01_100m'`~~ `'01_100'` という文字列を得る関数を作っておきます。
4
4
  ```python
5
5
  import re
6
6