0

df次の形式の長い DataFrameがあります。

user_id day action1 action2 action3 action4 action5
      1   0       4       2       0       1       0
      1   1       4       2       0       1       0
      2   1       4       2       0       1       0

アクション列の値は、ユーザーがその日にそのアクションを実行した回数を表します。これをワイドに変換したいのですDataFrameが、時間枠を任意に延長できます(たとえば、365日まで)。

次の方法で、かなり簡単にワイドに形状を変更できます。

df_indexed = df.set_index(['user_id', 'day'])
df_wide = df_indexed.unstack().fillna()

5 つのアクションのそれぞれについて、0 で埋められた残りの 358 日を追加するにはどうすればよいでしょうか?

4

2 に答える 2

1

これは@ViktorKerkezが使用を提案したものに似ていますpandas.merge

In [83]: df
Out[83]:
   user_id  day  action1  action2  action3  action4  action5
0        1    0        4        2        0        1        0
1        1    1        4        2        0        1        0
2        2    1        4        2        0        1        0

In [84]: days_joiner = DataFrame(dict(zip(['user_id', 'day'], zip(*list(itertools.product(df.user_id.unique(), range(365)))))))

In [85]: result = pd.merge(df, days_joiner, how='outer')

In [86]: result.head(10)
Out[86]:
   user_id  day  action1  action2  action3  action4  action5
0        1    0        4        2        0        1        0
1        1    1        4        2        0        1        0
2        2    1        4        2        0        1        0
3        1    2      NaN      NaN      NaN      NaN      NaN
4        1    3      NaN      NaN      NaN      NaN      NaN
5        1    4      NaN      NaN      NaN      NaN      NaN
6        1    5      NaN      NaN      NaN      NaN      NaN
7        1    6      NaN      NaN      NaN      NaN      NaN
8        1    7      NaN      NaN      NaN      NaN      NaN
9        1    8      NaN      NaN      NaN      NaN      NaN

In [87]: result.fillna(0).head(10)
Out[87]:
   user_id  day  action1  action2  action3  action4  action5
0        1    0        4        2        0        1        0
1        1    1        4        2        0        1        0
2        2    1        4        2        0        1        0
3        1    2        0        0        0        0        0
4        1    3        0        0        0        0        0
5        1    4        0        0        0        0        0
6        1    5        0        0        0        0        0
7        1    6        0        0        0        0        0
8        1    7        0        0        0        0        0
9        1    8        0        0        0        0        0

公平を期す%timeitために、2つの方法の比較を次に示します

In [90]: timeit pd.merge(df, days_joiner, how='outer')
1000 loops, best of 3: 1.33 ms per loop

In [96]: timeit df_indexed.reindex(index, fill_value=0)
10000 loops, best of 3: 146 µs per loop

私の答えは約9倍遅いです!

于 2013-08-15T23:02:02.487 に答える