私はデータフレームを持っています、
Out[78]:
contract month year buys adjusted_lots price
0 W Z 5 Sell -5 554.85
1 C Z 5 Sell -3 424.50
2 C Z 5 Sell -2 424.00
3 C Z 5 Sell -2 423.75
4 C Z 5 Sell -3 423.50
5 C Z 5 Sell -2 425.50
6 C Z 5 Sell -3 425.25
7 C Z 5 Sell -2 426.00
8 C Z 5 Sell -2 426.75
9 CC U 5 Buy 5 3328.00
10 SB V 5 Buy 5 11.65
11 SB V 5 Buy 5 11.64
12 SB V 5 Buy 2 11.60
他のすべての列でグループ化された、adjusted_lots、priceおよびajusted_lotsの加重平均であるpriceの合計が必要です。 (契約、月、年、買い)でグループ化
Rでの同様のソリューションは、dplyrを使用して次のコードで実現されましたが、パンダでは同じことができませんでした。
> newdf = df %>%
select ( contract , month , year , buys , adjusted_lots , price ) %>%
group_by( contract , month , year , buys) %>%
summarise(qty = sum( adjusted_lots) , avgpx = weighted.mean(x = price , w = adjusted_lots) , comdty = "Comdty" )
> newdf
Source: local data frame [4 x 6]
contract month year comdty qty avgpx
1 C Z 5 Comdty -19 424.8289
2 CC U 5 Comdty 5 3328.0000
3 SB V 5 Comdty 12 11.6375
4 W Z 5 Comdty -5 554.8500
groupbyまたは他のソリューションでも同じことが可能ですか?
Groupbyオブジェクトに複数の関数を渡すには、列に対応する集計関数を含む辞書を渡す必要があります。
# Define a lambda function to compute the weighted mean:
wm = lambda x: np.average(x, weights=df.loc[x.index, "adjusted_lots"])
# Define a dictionary with the functions to apply for a given column:
f = {'adjusted_lots': ['sum'], 'price': {'weighted_mean' : wm} }
# Groupby and aggregate with your dictionary:
df.groupby(["contract", "month", "year", "buys"]).agg(f)
adjusted_lots price
sum weighted_mean
contract month year buys
C Z 5 Sell -19 424.828947
CC U 5 Buy 5 3328.000000
SB V 5 Buy 12 11.637500
W Z 5 Sell -5 554.850000
詳細はこちらをご覧ください:
ここで同様の質問に:
お役に立てれば
Groupby(...)。apply(...)による加重平均を実行すると、非常に遅くなる可能性があります(以下から100倍)。 このスレッド の私の答え(およびその他)を参照してください。
def weighted_average(df,data_col,weight_col,by_col):
df['_data_times_weight'] = df[data_col]*df[weight_col]
df['_weight_where_notnull'] = df[weight_col]*pd.notnull(df[data_col])
g = df.groupby(by_col)
result = g['_data_times_weight'].sum() / g['_weight_where_notnull'].sum()
del df['_data_times_weight'], df['_weight_where_notnull']
return result
集計関数の辞書を使用するソリューションは、pandasの将来のバージョン(バージョン0.22)で非推奨になります。
FutureWarning: using a dict with renaming is deprecated and will be removed in a future
version return super(DataFrameGroupBy, self).aggregate(arg, *args, **kwargs)
Pandas集約からの結果列の名前変更( "FutureWarning:dictを使用して名前を変更することは推奨されていません")
def my_agg(x):
names = {'weighted_ave_price': (x['adjusted_lots'] * x['price']).sum()/x['adjusted_lots'].sum()}
return pd.Series(names, index=['weighted_ave_price'])
同じ結果を生成します。
>df.groupby(["contract", "month", "year", "buys"]).apply(my_agg)
weighted_ave_price
contract month year buys
C Z 5 Sell 424.828947
CC U 5 Buy 3328.000000
SB V 5 Buy 11.637500
W Z 5 Sell 554.850000