web-dev-qa-db-ja.com

パンダ:値が範囲内にある場所に基づいてカテゴリを割り当てます

次の範囲とpandas DataFrame:

x >= 0        # success
-10 <= x < 0  # warning
X < -10       # danger

df = pd.DataFrame({'x': [2, 1], 'y': [-7, -5], 'z': [-30, -20]})

定義された範囲内のどこにあるかに基づいて、DataFrameの値を分類したいと思います。したがって、最終的なDFは次のようになります。

    x    y    z    x_cat    y_cat    z_cat
0   2   -7  -30  success  warning   danger
1   1   -5  -20  success  warning   danger

categoryデータ型を使用してみましたが、どこでも範囲を定義できるとは思われません。

for category_column, value_column in Zip(['x_cat', 'y_cat', 'z_cat'], ['x', 'y', 'z']):
    df[category_column] = df[value_column].astype('category')

categoryデータ型を使用できますか?そうでない場合、私はここで何ができますか?

8
Johnny Metz

pandas.cut

c = pd.cut(
    df.stack(),
    [-np.inf, -10, 0, np.inf],
    labels=['danger', 'warning', 'success']
)
df.join(c.unstack().add_suffix('_cat'))

   x  y   z    x_cat    y_cat   z_cat
0  2 -7 -30  success  warning  danger
1  1 -5 -20  success  warning  danger

numpy

v = df.values
cats = np.array(['danger', 'warning', 'success'])
code = np.searchsorted([-10, 0], v.ravel()).reshape(v.shape)
cdf = pd.DataFrame(cats[code], df.index, df.columns)
df.join(cdf.add_suffix('_cat'))

   x  y   z    x_cat    y_cat   z_cat
0  2 -7 -30  success  warning  danger
1  1 -5 -20  success  warning  danger
17
piRSquared

assignを使用して新しい列を作成できます。新しい列ごとに、系列をフィルタリングするために適用を使用します。

df.assign(x_cat = lambda v: v.x.apply(lambda x: 'Sucess' if x>=0 else None),
         y_cat = lambda v: v.y.apply(lambda x: 'warning' if -10<=x<0 else None),
         z_cat = lambda v: v.z.apply(lambda x: 'danger' if x<=-10 else None),)

結果になります

    x   y   z   x_cat   y_cat   z_cat
0   2   -7  -30 Sucess  warning danger
1   1   -5  -20 Sucess  warning danger
3
plasmon360

pandas cut を使用できますが、列ごとに適用する必要があります(関数が1-d入力で動作するため):

labels = df.apply(lambda x: pd.cut(x, [-np.inf, -10, 0, np.inf], labels = ['danger', 'warning', 'success']))

          x        y       z
0  success  warning  danger
1  success  warning  danger

だからあなたはできる:

pd.concat([df, labels.add_prefix('_cat')], axis = 1)

   x  y   z     cat_x     cat_y    cat_z
0  2 -7 -30  success  warning  danger
1  1 -5 -20  success  warning  danger
2
FLab

小さな関数を記述してから、applyを使用して各シリーズを関数に渡すことができます。

df = pd.DataFrame({'x': [2, 1], 'y': [-7, -5], 'z': [-30, -20]})

def cat(x):
    if x <-10:
        return "Danger"
    if x < 0:
        return "Warning"
    return "Success"

for col in df.columns:
    df[col] = df[col].apply(lambda x: cat(x))
2
Woody Pride

この種のものの3元法を次に示します。

filter_method = lambda x: 'success' if x >= 0 else 'warning' if (x < 0 and x >= -10) else 'danger' if x < -10 else None
df[category_column] = df[value_column].apply(filter_method)
0
Quentin