回答編集履歴

2

修正

2020/03/16 05:01

投稿

kirara0048
kirara0048

スコア1399

test CHANGED
@@ -212,6 +212,32 @@
212
212
 
213
213
  ```python
214
214
 
215
+ # NumPy配列に変換
216
+
217
+ arr = df.to_numpy()
218
+
219
+ # もし、'id1', 'id2'の組み合わせが網羅的でなく、ソートされていない場合(例えば、
220
+
221
+ print(df.sample(frac=0.9, random_state=0))
222
+
223
+ # item1 item2 item3
224
+
225
+ # id1 id2
226
+
227
+ # 2 2 4 5 6
228
+
229
+ # 1 1 2 3
230
+
231
+ # 3 7 8 9
232
+
233
+ # 1 3 7 8 9
234
+
235
+ # 3 1 1 2 3
236
+
237
+ # 3 7 8 9
238
+
239
+ # 1 2 4 5 6 のようなとき)
240
+
215
241
  # 'id1', 'id2'の組み合わせを網羅させ、NumPy配列に変換
216
242
 
217
243
  arr = df.reindex(pd.MultiIndex.from_product(df.index.levels)).to_numpy()
@@ -220,7 +246,7 @@
220
246
 
221
247
  # `ndarray.reshape()`を用いて組み換え、データフレームに変換
222
248
 
223
- col = pd.MultiIndex.from_product((df.columns, df.index.levels[1]))
249
+ col = pd.MultiIndex.from_product((df.index.levels[1], df.columns))
224
250
 
225
251
  new_df = pd.DataFrame(arr.reshape(df.index.levshape[0], -1),
226
252
 
@@ -238,7 +264,7 @@
238
264
 
239
265
 
240
266
 
241
- | id1 | item1-1 | item1-2 | item1-3 | item2-1 | item2-2 | item2-3 | item3-1 | item3-2 | item3-3 |
267
+ | id1 | item1-1 | item2-1 | item3-1 | item1-2 | item2-2 | item3-2 | item1-3 | item2-3 | item3-3 |
242
268
 
243
269
  |------:|----------:|----------:|----------:|----------:|----------:|----------:|----------:|----------:|----------:|
244
270
 

1

手法を追加

2020/03/16 05:01

投稿

kirara0048
kirara0048

スコア1399

test CHANGED
@@ -4,6 +4,16 @@
4
4
 
5
5
 
6
6
 
7
+ また、`id1`・`id2`列がインデックスに設定されている場合は、`df.unstack()`を用いることができます。
8
+
9
+ [pandas.DataFrame.unstack — pandas 1.0.2 documentation](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.unstack.html#pandas-dataframe-unstack)
10
+
11
+
12
+
13
+ ## ケース1
14
+
15
+
16
+
7
17
  ```python
8
18
 
9
19
  data = {'id1': [1, 1, 1, 2, 2, 2],
@@ -66,7 +76,7 @@
66
76
 
67
77
 
68
78
 
69
- また
79
+ 質問にある例と全く同一の形式に変換するには
70
80
 
71
81
 
72
82
 
@@ -93,3 +103,145 @@
93
103
  | 1 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
94
104
 
95
105
  | 2 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
106
+
107
+
108
+
109
+ ## ケース2(`id`列がindexのとき)
110
+
111
+
112
+
113
+ ```python
114
+
115
+ data = {'id1': [1, 1, 1, 2, 2, 2],
116
+
117
+ 'id2': [1, 2, 3, 1, 2, 3],
118
+
119
+ 'item1': [1, 4, 7, 1, 4, 7],
120
+
121
+ 'item2': [2, 5, 8, 2, 5, 8],
122
+
123
+ 'item3': [3, 6, 9, 3, 6, 9]}
124
+
125
+ df = pd.DataFrame(data).set_index(['id1', 'id2'])
126
+
127
+ print(df)
128
+
129
+ ```
130
+
131
+
132
+
133
+ | | item1 | item2 | item3 |
134
+
135
+ |:-------|--------:|--------:|--------:|
136
+
137
+ | (1, 1) | 1 | 2 | 3 |
138
+
139
+ | (1, 2) | 4 | 5 | 6 |
140
+
141
+ | (1, 3) | 7 | 8 | 9 |
142
+
143
+ | (2, 1) | 1 | 2 | 3 |
144
+
145
+ | (2, 2) | 4 | 5 | 6 |
146
+
147
+ | (2, 3) | 7 | 8 | 9 |
148
+
149
+
150
+
151
+ このとき、
152
+
153
+
154
+
155
+ ```python
156
+
157
+ new_df = df.unstack()
158
+
159
+ new_df.sort_index(axis=1, level=1, inplace=True)
160
+
161
+ new_df.set_axis(['-'.join([c1, str(c2)]) for c1, c2 in new_df.columns],
162
+
163
+ axis=1, inplace=True)
164
+
165
+ print(new_df)
166
+
167
+ ```
168
+
169
+
170
+
171
+ | id1 | item1-1 | item2-1 | item3-1 | item1-2 | item2-2 | item3-2 | item1-3 | item2-3 | item3-3 |
172
+
173
+ |------:|----------:|----------:|----------:|----------:|----------:|----------:|----------:|----------:|----------:|
174
+
175
+ | 1 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
176
+
177
+ | 2 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
178
+
179
+
180
+
181
+ ## ケース3(NumPyを使う方法)
182
+
183
+
184
+
185
+ `id1`・`id2`列がインデックスに設定されていて、`id1`と`id2`の組み合わせが全て網羅されている場合、3*3ブロックを1*9に組み替えるだけでいいので、以下の方法が使えます。
186
+
187
+
188
+
189
+ ```python
190
+
191
+ data = {'id1': [1, 1, 1, 2, 2, 2],
192
+
193
+ 'id2': [1, 2, 3, 1, 2, 3],
194
+
195
+ 'item1': [1, 4, 7, 1, 4, 7],
196
+
197
+ 'item2': [2, 5, 8, 2, 5, 8],
198
+
199
+ 'item3': [3, 6, 9, 3, 6, 9]}
200
+
201
+ df = pd.DataFrame(data).set_index(['id1', 'id2'])
202
+
203
+ # ケース2と同じ
204
+
205
+ ```
206
+
207
+
208
+
209
+ このとき、
210
+
211
+
212
+
213
+ ```python
214
+
215
+ # 'id1', 'id2'の組み合わせを網羅させ、NumPy配列に変換
216
+
217
+ arr = df.reindex(pd.MultiIndex.from_product(df.index.levels)).to_numpy()
218
+
219
+
220
+
221
+ # `ndarray.reshape()`を用いて組み換え、データフレームに変換
222
+
223
+ col = pd.MultiIndex.from_product((df.columns, df.index.levels[1]))
224
+
225
+ new_df = pd.DataFrame(arr.reshape(df.index.levshape[0], -1),
226
+
227
+ index=df.index.levels[0], columns=col)
228
+
229
+
230
+
231
+ new_df.set_axis(['-'.join([c1, str(c2)]) for c1, c2 in new_df.columns],
232
+
233
+ axis=1, inplace=True)
234
+
235
+ print(new_df)
236
+
237
+ ```
238
+
239
+
240
+
241
+ | id1 | item1-1 | item1-2 | item1-3 | item2-1 | item2-2 | item2-3 | item3-1 | item3-2 | item3-3 |
242
+
243
+ |------:|----------:|----------:|----------:|----------:|----------:|----------:|----------:|----------:|----------:|
244
+
245
+ | 1 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
246
+
247
+ | 2 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |