Python Pandas Jak przypisać wyniki operacji Groupby do kolumn w macierzystej ramce danych?

Mam w IPythonie następującą ramkę danych, gdzie każdy wiersz to pojedynczy zapas:

In [261]: bdata
Out[261]:
<class 'pandas.core.frame.DataFrame'>
Int64Index: 21210 entries, 0 to 21209
Data columns:
BloombergTicker      21206  non-null values
Company              21210  non-null values
Country              21210  non-null values
MarketCap            21210  non-null values
PriceReturn          21210  non-null values
SEDOL                21210  non-null values
yearmonth            21210  non-null values
dtypes: float64(2), int64(1), object(4)

Chcę zastosować operację grupowania, która oblicza średnią ważoną stopę zwrotu we wszystkich punktach na każdą datę w kolumnie „yearmonth”.

Działa to zgodnie z oczekiwaniami:

In [262]: bdata.groupby("yearmonth").apply(lambda x: (x["PriceReturn"]*x["MarketCap"]/x["MarketCap"].sum()).sum())
Out[262]:
yearmonth
201204      -0.109444
201205      -0.290546

Ale potem chcę posortować te wartości z powrotem do indeksów w oryginalnej ramce danych i zapisać je jako stałe kolumny, w których daty się zgadzają.

In [263]: dateGrps = bdata.groupby("yearmonth")

In [264]: dateGrps["MarketReturn"] = dateGrps.apply(lambda x: (x["PriceReturn"]*x["MarketCap"]/x["MarketCap"].sum()).sum())
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/mnt/bos-devrnd04/usr6/home/espears/ws/Research/Projects/python-util/src/util/<ipython-input-264-4a68c8782426> in <module>()
----> 1 dateGrps["MarketReturn"] = dateGrps.apply(lambda x: (x["PriceReturn"]*x["MarketCap"]/x["MarketCap"].sum()).sum())

TypeError: 'DataFrameGroupBy' object does not support item assignment

Zdaję sobie sprawę, że to naiwne zadanie nie powinno działać. Ale jaki jest „właściwy” idiom Pand do przypisywania wyniku operacji Groupby do nowej kolumny nadrzędnej ramki danych?

Na koniec chcę, aby kolumna o nazwie „MarketReturn” była powtarzaną stałą wartością dla wszystkich indeksów, które mają datę pasującą do wyniku operacji groupby.

Jeden hack do osiągnięcia tego celu to:

marketRetsByDate  = dateGrps.apply(lambda x: (x["PriceReturn"]*x["MarketCap"]/x["MarketCap"].sum()).sum())

bdata["MarketReturn"] = np.repeat(np.NaN, len(bdata))

for elem in marketRetsByDate.index.values:
    bdata["MarketReturn"][bdata["yearmonth"]==elem] = marketRetsByDate.ix[elem]

Ale to jest powolne, złe i niepythoniczne.

questionAnswers(5)

yourAnswerToTheQuestion