/ / Python Pandasグループに基づいてグループ化し、最大値を取得しますが、別の列に基づいて除外します - python、pandas

Python Pandasグループは列に基づいて最大値を取得しますが、別の列に基づいて除外します - python、pandas

私はいくつかのデータを扱っているので引っ張りたいと思います特定の列の最大値。別の列でグループ化されています。ただし、別の列に基づいて、最大計算から特定の行を除外します。

例:

df = pd.DataFrame({"Col1":["A","A","A","B","B","B","B"],
"Col2":["Build","Plan","Other","Test","Build","Other","Buy"],
"Col3":[2,5,17,5,13,12,12]})

Col2に "Other"を含む行を除外しながら、Col1でグループ化されたCol3の最大値を取得したいしたがって、 "A"のCol3の最大値は17ではなく5になります。

Col1によってグループ化されたCol3の最大値を取得することができました。 df["new"] = df.groupby(["Col1"])["Col3"].transform(max) ただし、これにより、Aの値は17になります。

他のスレッドを見回すことから、私は使ってみました:

x = df1.groupby(["Col1"])
x2 = x.apply(lambda g: g[g["Col2"] != "Other"])

そしてこれは私を近づけるように思われる(それはCol1によってグループ化されたデータを持ち、Col2に基づいて行が削除される)。しかし、私はもうCol1に基づいてCol3の最大値を取得する方法を見つけることができないようです。

せいぜい私は使用することができました: x2["Col3"].max() Col2の "Other"ですべての行を削除した後、Col3の最大値を取得します。しかし、Col1でCol3をグループ化した最大値を取得することはできません。

まったく新しいオーダーメイドの関数を作成する代わりに、これを比較的簡単に行うために作り付けのPandas関数を使用する方法があるのではないかと思いましたか?

回答:

回答№1の場合は3

あなたが試すことができます

df[df.Col2 != "Other"].groupby("Col1").Col3.max()

Col1
A     5
B    13

新しい列を作成するには

df["new"]=df[df.Col2 != "Other"].groupby("Col1").Col3.transform("max")
df["new"] = df.new.ffill()

Col1    Col2    Col3    new
0   A       Build   2       5.0
1   A       Plan    5       5.0
2   A       Other   17      5.0
3   B       Test    5       13.0
4   B       Build   13      13.0
5   B       Other   12      13.0
6   B       Buy     12      13.0

説明:Col2の値が "Other"に等しくない、Col1によるグループ化、Col3の最大値のdfの行のみを選択してください。

ここに transformのドキュメントです。 集計ではなく、変換された値を含む類似のインデックス付きdfを返します。


回答№2の場合は1

を使ってそれを混同するもう一つの方法 groupby

df.groupby([df.Col2.ne("Other"), "Col1"]).Col3.max()[True]

Col1
A     5
B    13
Name: Col3, dtype: int64

回答№3の場合は0

@Vaishaliの答えは良いスタートですが私はnaを取り除くためにffillを適用するときに特に問題がある可能性があると思います。 この方法が機能するためには、データフレームを特定の方法でソートする必要があります。 納得するために、これを試してください:

df = pd.DataFrame({"Col1":["A","A","A","B","B","B","B","C", "C"],
"Col2":["Build","Plan","Other","Test","Build","Other","Buy", "Buy","Other"],
"Col3":[2,5,17,5,13,12,12,14,5]})
df = df.sample(frac=1) #shuffle rows

df["new"]=df[df.Col2 != "Other"].groupby("Col1")["Col3"].transform("max")
df["new"] = df.new.ffill()

そして、あなたはこの結果を得ることができますが、これは良くありません。

Col1    Col2    Col3    new
3   B   Test    5   13.0
7   C   Buy     14  14.0
6   B   Buy     12  13.0
1   A   Plan    5   5.0
0   A   Build   2   5.0
5   B   Other   12  5.0
8   C   Other   5   5.0
4   B   Build   13  13.0
2   A   Other   17  13.0

より良い解決策: まずこの関数を定義してください。

def new_transform(df, exclude_cond,gbycol,target, agg_fun, ignore_value=None):
df["target_temp"] = df[target]
df.loc[eval(exclude_cond), "target_temp"] = ignore_value
tmp=df.groupby(gbycol)["target_temp"].transform(agg_fun)
df.drop("target_temp", axis=1, inplace=True)
return tmp

データフレーム、exculde_condはstring、文字列のリストとしてのgroupby、または文字列、計算対象のtarget:列名、集計関数、および集計関数で無視される値(主要なagg関数にはNoneが使用されます)。

例:

df = pd.DataFrame({"Col1":["A","A","A","B","B","B","B","C", "C"],
"Col2":["Build","Plan","Other","Test","Build","Other","Buy", "Buy","Other"],
"Col3":[2,5,17,5,13,12,12,14,5]})
df = df.sample(frac=1)
df["new"]=new_transform(df, "df["Col2"]=="Build"", ["Col1"],"Col3", "sum", np.nan)

正しい計算式が得られます。

  Col1  Col2    Col3    new
3   B   Test    5     29.0
2   A   Other   17    22.0
4   B   Build   13    29.0
6   B   Buy     12    29.0
7   C   Buy     14    19.0
1   A   Plan    5     22.0
5   B   Other   12    29.0
0   A   Build   2     22.0
8   C   Other   5     19.0