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