Survived SibSp Parch
0 0 1 0
1 1 1 0
2 1 0 0
3 1 1 0
4 0 0 1
上記のデータフレームを考えると、条件付きでgroupby
するエレガントな方法はありますか?次の条件に基づいて、データを2つのグループに分割したいと思います。
(df['SibSp'] > 0) | (df['Parch'] > 0) = New Group -"Has Family"
(df['SibSp'] == 0) & (df['Parch'] == 0) = New Group - "No Family"
次に、これらのグループの両方の手段を取り、次のような出力になります。
SurvivedMean
Has Family Mean
No Family Mean
Groupbyを使用して実行できますか、それとも上記の条件ステートメントを使用して新しい列を追加する必要がありますか?
グループ化する簡単な方法は、これら2つの列の合計を使用することです。いずれかが正の場合、結果は1より大きくなります。また、groupbyは、長さがDataFrameの長さと同じである限り、任意の配列を受け入れるため、新しい列を追加する必要はありません。
family = np.where((df['SibSp'] + df['Parch']) >= 1 , 'Has Family', 'No Family')
df.groupby(family)['Survived'].mean()
Out:
Has Family 0.5
No Family 1.0
Name: Survived, dtype: float64
列SibSp
およびParch
の値が0
よりも小さい場合は、1つの条件のみを使用してください。
m1 = (df['SibSp'] > 0) | (df['Parch'] > 0)
df = df.groupby(np.where(m1, 'Has Family', 'No Family'))['Survived'].mean()
print (df)
Has Family 0.5
No Family 1.0
Name: Survived, dtype: float64
不可能な場合は、最初に両方の条件を使用してください。
m1 = (df['SibSp'] > 0) | (df['Parch'] > 0)
m2 = (df['SibSp'] == 0) & (df['Parch'] == 0)
a = np.where(m1, 'Has Family',
np.where(m2, 'No Family', 'Not'))
df = df.groupby(a)['Survived'].mean()
print (df)
Has Family 0.5
No Family 1.0
Name: Survived, dtype: float64
リストで条件を定義し、以下の関数group_by_condition
を使用して、条件ごとにフィルター処理されたリストを作成できます。その後、パターンマッチングを使用して、結果のアイテムを選択できます。
df = [
{"Survived": 0, "SibSp": 1, "Parch": 0},
{"Survived": 1, "SibSp": 1, "Parch": 0},
{"Survived": 1, "SibSp": 0, "Parch": 0}]
conditions = [
lambda x: (x['SibSp'] > 0) or (x['Parch'] > 0), # has family
lambda x: (x['SibSp'] == 0) and (x['Parch'] == 0) # no family
]
def group_by_condition(l, conditions):
return [[item for item in l if condition(item)] for condition in conditions]
[has_family, no_family] = group_by_condition(df, conditions)