回答編集履歴
1
いろんなコードを試行してみました
answer
CHANGED
@@ -1,11 +1,29 @@
|
|
1
|
+
その1:質問のコードを直したもの
|
2
|
+
|
1
3
|
```python
|
2
|
-
df['Season'].astype(str).str.cat([
|
4
|
+
df["ID"] = df['Season'].astype(str).str.cat([
|
3
5
|
df[['WTeamID', 'LTeamID']].min(1).astype(str),
|
4
6
|
df[['WTeamID', 'LTeamID']].max(1).astype(str)], '_')
|
5
7
|
```
|
6
8
|
|
7
|
-
|
9
|
+
その2:より簡単なコード
|
8
10
|
|
11
|
+
```python
|
12
|
+
df["ID"] = df['Season'].astype(str).str.cat(
|
13
|
+
np.sort(df[['LTeamID', 'WTeamID']].to_numpy()).astype(str), '_')
|
14
|
+
```
|
15
|
+
|
16
|
+
その3:リストを使う方法
|
17
|
+
|
18
|
+
```python
|
19
|
+
arr_s = df['Season'].tolist()
|
20
|
+
arr_lw = np.sort(df[['LTeamID', 'WTeamID']].to_numpy()).tolist()
|
21
|
+
df["ID"] = pd.Series([f'{s}_{lw[0]}_{lw[1]}' for s, lw in zip(arr_s, arr_lw)],
|
22
|
+
index=df.index)
|
23
|
+
```
|
24
|
+
|
25
|
+
## 解説(その1)
|
26
|
+
|
9
27
|
> ①str(df["Season"]) のoutputがdataframe形式で返されない
|
10
28
|
|
11
29
|
`str()`は文字列型を返す関数です。`pd.Series`(或いは`pd.DataFrame`)のデータ型を文字列型(正確にはオブジェクト型)にする場合は`pd.Series.astype(str)`を使います。
|
@@ -87,10 +105,10 @@
|
|
87
105
|
したがって、
|
88
106
|
|
89
107
|
```python
|
90
|
-
In [
|
108
|
+
In [26]: df['Season'].astype(str).str.cat([
|
91
109
|
2 df[['WTeamID', 'LTeamID']].min(1).astype(str),
|
92
110
|
3 df[['WTeamID', 'LTeamID']].max(1).astype(str)], '_')
|
93
|
-
Out[
|
111
|
+
Out[26]:
|
94
112
|
1916 2015_1214_1264
|
95
113
|
1917 2015_1140_1279
|
96
114
|
1918 2015_1129_1173
|
@@ -103,4 +121,83 @@
|
|
103
121
|
1981 2015_1246_1458
|
104
122
|
1982 2015_1181_1458
|
105
123
|
Name: Season, dtype: object
|
106
|
-
```
|
124
|
+
```
|
125
|
+
|
126
|
+
## 解説(その2)
|
127
|
+
|
128
|
+
今回の場合、数値を比較して「小さい方_大きい方」という部分がありますが、この部分は`np.sort()`を使うって行ごとに「小さい→大きい」順に並べ替えした配列を作るのが簡便です。
|
129
|
+
つまり、
|
130
|
+
|
131
|
+
```python
|
132
|
+
In [5]: arr = np.sort(df[['LTeamID', 'WTeamID']].to_numpy())
|
133
|
+
2 arr
|
134
|
+
Out[5]:
|
135
|
+
array([[1214, 1264],
|
136
|
+
[1140, 1279],
|
137
|
+
[1129, 1173],
|
138
|
+
[1316, 1352],
|
139
|
+
[1112, 1411],
|
140
|
+
... ...
|
141
|
+
[1181, 1211],
|
142
|
+
[1257, 1277],
|
143
|
+
[1181, 1277],
|
144
|
+
[1246, 1458],
|
145
|
+
[1181, 1458]], dtype=int64)
|
146
|
+
|
147
|
+
In [6]: df['Season'].astype(str).str.cat(arr.astype(str), '_')
|
148
|
+
Out[6]:
|
149
|
+
1916 2015_1214_1264
|
150
|
+
1917 2015_1140_1279
|
151
|
+
1918 2015_1129_1173
|
152
|
+
1919 2015_1316_1352
|
153
|
+
1920 2015_1112_1411
|
154
|
+
... ...
|
155
|
+
1978 2015_1181_1211
|
156
|
+
1979 2015_1257_1277
|
157
|
+
1980 2015_1181_1277
|
158
|
+
1981 2015_1246_1458
|
159
|
+
1982 2015_1181_1458
|
160
|
+
Name: Season, dtype: object
|
161
|
+
```
|
162
|
+
|
163
|
+
## 解説(その3)
|
164
|
+
|
165
|
+
pandasの`str`関連メソッドは実際にはとても動作が遅いです。標準のリストになおしてforループした方が速い場合があります。
|
166
|
+
|
167
|
+
```python
|
168
|
+
In [11]: arr_s = df['Season'].tolist()
|
169
|
+
2 arr_lw = np.sort(df[['LTeamID', 'WTeamID']].to_numpy()).tolist()
|
170
|
+
3 id_list = [f'{s}_{lw[0]}_{lw[1]}' for s, lw in zip(arr_s, arr_lw)]
|
171
|
+
4 id_list
|
172
|
+
Out[11]:
|
173
|
+
['2015_1214_1264',
|
174
|
+
'2015_1140_1279',
|
175
|
+
'2015_1129_1173',
|
176
|
+
'2015_1316_1352',
|
177
|
+
'2015_1112_1411',
|
178
|
+
'2015_1181_1211',
|
179
|
+
'2015_1257_1277',
|
180
|
+
'2015_1181_1277',
|
181
|
+
'2015_1246_1458',
|
182
|
+
'2015_1181_1458']
|
183
|
+
|
184
|
+
In [12]: pd.Series(id_list, index=df.index)
|
185
|
+
Out[12]:
|
186
|
+
1916 2015_1214_1264
|
187
|
+
1917 2015_1140_1279
|
188
|
+
1918 2015_1129_1173
|
189
|
+
1919 2015_1316_1352
|
190
|
+
1920 2015_1112_1411
|
191
|
+
1978 2015_1181_1211
|
192
|
+
1979 2015_1257_1277
|
193
|
+
1980 2015_1181_1277
|
194
|
+
1981 2015_1246_1458
|
195
|
+
1982 2015_1181_1458
|
196
|
+
dtype: object
|
197
|
+
```
|
198
|
+
|
199
|
+
## 処理速度の比較
|
200
|
+
|
201
|
+

|
202
|
+
|
203
|
+
その3(リストを使う方法)が最も速いようです。@can110氏の方法(`df.apply`を使った方法)はデータ数が少ないときは次いで速いですが、行数が増えるとかなり遅くなります。
|