web-dev-qa-db-ja.com

Pandas dataframeの数値データをカテゴリ/ビンにマッピングする方法

私はPythonでコーディングを始めたばかりで、私の一般的なコーディングスキルはかなり錆びています:(少しお待ちください

pandasデータフレーム:

SamplePandas

約3mの行があります。 age_unitsには、Y、D、Wの年、Days&Weeksの3種類があります。 1歳以上の個人の年齢単位はYであり、最初に必要なグループは2歳未満なので、年齢単位でテストする必要があるのはYのみです...

新しい列AgeRangeを作成し、次の範囲を設定します。

  • <2
  • 2〜18
  • 18〜35
  • 35〜65
  • 65+

だから私は関数を書いた

def agerange(values):
    for i in values:
        if complete.Age_units == 'Y':
            if complete.Age > 1 AND < 18 return '2-18'
            Elif complete.Age > 17 AND < 35 return '18-35'
            Elif complete.Age > 34 AND < 65 return '35-65'
            Elif complete.Age > 64 return '65+'
        else return '< 2'

データフレーム全体を渡した場合、必要なものを取り戻し、次のような列を作成できると考えました。

agedetails['age_range'] = ageRange(agedetails)

しかし、私が取得する関数を作成する最初のコードを実行しようとすると:

  File "<ipython-input-124-cf39c7ce66d9>", line 4
    if complete.Age > 1 AND complete.Age < 18 return '2-18'
                          ^
SyntaxError: invalid syntax

明らかにそれはANDを受け入れていませんが、クラスでこのようにANDを使用できると聞いたと思いますか?私は間違っている必要がありますが、これを行う正しい方法は何でしょうか?

そのため、そのエラーを取得した後、データフレームを渡す方法でもエラーがスローされるかどうかはわかりません。おそらくそうだと思います。どの場合に-どのように私もそれを機能させるのでしょうか?

私は最高の方法を学びたいと思っていますが、私にとって最良の方法の一部は、それが数ステップで物事を行うことを意味する場合でも、それをシンプルに保つことです...

8
kiltannen

Pandasでは、行単位の操作は通常、非効率的なPythonレベルのループを伴うため、避ける必要があります。いくつかの選択肢があります。

パンダ: pd.cut

@JonClementsが示唆するように、pd.cutこのため、ここでの利点は、新しい列が Categorical になることです。

境界を定義する必要があるだけです(np.inf)およびカテゴリ名、次にpd.cutを目的の数値列に。

bins = [0, 2, 18, 35, 65, np.inf]
names = ['<2', '2-18', '18-35', '35-65', '65+']

df['AgeRange'] = pd.cut(df['Age'], bins, labels=names)

print(df.dtypes)

# Age             int64
# Age_units      object
# AgeRange     category
# dtype: object

NumPy: np.digitize

np.digitizeは、別のクリーンなソリューションを提供します。アイデアは、境界と名前を定義し、辞書を作成してからnp.digitizeを[年齢]列に追加します。最後に、辞書を使用してカテゴリ名をマッピングします。

境界の場合、ビンへのマッピングには下限が使用されることに注意してください。

import pandas as pd, numpy as np

df = pd.DataFrame({'Age': [99, 53, 71, 84, 84],
                   'Age_units': ['Y', 'Y', 'Y', 'Y', 'Y']})

bins = [0, 2, 18, 35, 65]
names = ['<2', '2-18', '18-35', '35-65', '65+']

d = dict(enumerate(names, 1))

df['AgeRange'] = np.vectorize(d.get)(np.digitize(df['Age'], bins))

結果

   Age Age_units AgeRange
0   99         Y      65+
1   53         Y    35-65
2   71         Y      65+
3   84         Y      65+
4   84         Y      65+
24
jpp