69182
初めまして、Pythonおよびデータ分析初心者です。主にPandasとNumpy,Sklearnを使ってkaggle等のコンペに挑戦している最中の者です。

データセットをロジスティック回帰によって分析したいのですが、質的データであればpd.getdummies()で簡単にダミー変数を作ることができることを最近学びました。しかし年齢のように現在扱っているデータもを区画ごとにダミー変数化する必要があると考えて調べているのですが、なかなか良い方法が探せずに居ます。具体的には年齢に対して0-20,20-40,40-60,60-
という新しい列を作り、それに該当するか否かで0,1の値を割り振りたいと考えています。

```

    import pandas as pd 
    import numpy as np
    
    ID = np.arange(1,101) 
    #ID.shape
    Age = np.random.randint(0,100,100)
    #Age.shape
    
    DF = pd.DataFrame([ID,Age]).T
    DF.columns = ["ID","Age"]
    #DF
    
```

[![画像の説明をここに入力](https://i.stack.imgur.com/XnisR.png)](https://i.stack.imgur.com/XnisR.png)

このようなテーブルに対して、以下のような変換方法はございませんでしょうか。

[![画像の説明をここに入力](https://i.stack.imgur.com/J1jWn.png)](https://i.stack.imgur.com/J1jWn.png)

Pythonやデータ分析に関して何かご知見ございましたら、お答えいただけると幸いです。  
よろしくお願いいたします。
CC BY-SA 4.0
2020-08-02T05:14:12.037
69173
2020-08-02T09:19:35.227
2020-08-02T06:20:28.970
3060
41347
question
python pandas numpy
年齢を区間ごとにダミー変数化したい
ややアドホックですが、

```

    dummy_df["Age[21:41]"] = df.apply(lambda row: int(row.Age >= 21 and row.Age < 41), axis=1)
    
```

のように使いたい条件式を使ってそれぞれの列の 0, 1 を計算するのは如何でしょうか。今回は列の数も少ないのでこんな感じで良さそうです。

以下、完全なコード例です。

```

    >>> import numpy as np
    >>> import pandas as pd
    >>> age = np.random.randint(0,100,100)
    >>> df = pd.DataFrame(age, columns=["Age"])
    >>> df
        Age
    0    29
    1    86
    2    79
    3    80
    4    77
    ..  ...
    95   53
    96   11
    97   14
    98   89
    99   75
    
    [100 rows x 1 columns]
    >>> dummy_df = pd.DataFrame()
    >>> dummy_df["Age[:21]"] = df.apply(lambda row: int(row.Age < 21), axis=1)
    >>> dummy_df["Age[21:41]"] = df.apply(lambda row: int(row.Age >= 21 and row.Age < 41), axis=1)
    >>> dummy_df["Age[41:61]"] = df.apply(lambda row: int(row.Age >= 41 and row.Age < 61), axis=1)
    >>> dummy_df["Age[61:]"] = df.apply(lambda row: int(row.Age >= 61), axis=1)
    >>> dummy_df
        Age[:21]  Age[21:41]  Age[41:61]  Age[61:]
    0          0           1           0         0
    1          0           0           0         1
    2          0           0           0         1
    3          0           0           0         1
    4          0           0           0         1
    ..       ...         ...         ...       ...
    95         0           0           1         0
    96         1           0           0         0
    97         1           0           0         0
    98         0           0           0         1
    99         0           0           0         1
    
    [100 rows x 4 columns]
    
```

※ところで、0～20、21～40、41～60 という分け方だと、それぞれに含まれる年齢が 21 個、20 個、20
個となってしまいますがこれであっていますか？ 0～19、20～39、40～59 の方が適切そうです。
CC BY-SA 4.0
2020-08-02T05:36:17.037
69175
2020-08-02T05:36:17.037
19110
69173
answer
以下は
[numpy.searchsorted](https://numpy.org/doc/stable/reference/generated/numpy.searchsorted.html)
を使う方法です。

```

    import pandas as pd
    import numpy as np
    
    df = pd.DataFrame({
      'ID': range(1, 7),
      'Age': [13, 8, 92, 86, 26, 96]
    }, dtype=int)
    
    bins = range(0, 61, 20)
    binned = np.searchsorted(bins, df.Age.values) - 1
    data = np.zeros((len(df), len(bins)), dtype=int)
    data[np.arange(len(df)), binned] = 1
    
    columns = ['ID'] + \
      [f'Age({s+1 if s>0 else s}, {e})' for s, e in zip(bins, bins[1:])] + \
      [f'Age({bins[-1]+1}-)']
    
    dfn = pd.DataFrame(np.column_stack([df.ID, data]), columns=columns)
    
    print(dfn)
    
       ID  Age(0, 20)  Age(21, 40)  Age(41, 60)  Age(61-)
    0   1           1            0            0         0
    1   2           1            0            0         0
    2   3           0            0            0         1
    3   4           0            0            0         1
    4   5           0            1            0         0
    5   6           0            0            0         1
    
```
CC BY-SA 4.0
2020-08-02T08:33:01.537
69182
2020-08-02T09:19:35.227
2020-08-02T09:19:35.227
69173
answer