添加一列我有結構化的這樣一個數據幀:與GROUPBY的分層數據幀
First A B
Second bar baz foo bar baz foo
Third cat dog cat dog cat dog cat dog cat dog cat dog
0 3 8 7 7 4 7 5 3 2 2 6 2
1 8 6 5 7 8 7 1 8 6 0 3 9
2 9 2 2 9 7 3 1 8 4 1 0 8
3 3 6 0 6 3 2 2 6 2 4 6 9
4 7 6 4 3 1 5 0 4 8 4 8 1
所以有三個欄的水平。我想在第二級添加一個新列,在這裏爲每個第三級執行一次計算,例如'new'='foo'+'bar'。因此,所產生的數據幀將如下所示:
First A B
Second bar baz foo new bar baz foo new
Third cat dog cat dog cat dog cat dog cat dog cat dog cat dog cat dog
0 3 8 7 7 4 7 7 15 5 3 2 2 6 2 11 5
1 8 6 5 7 8 7 16 13 1 8 6 0 3 9 4 17
2 9 2 2 9 7 3 16 5 1 8 4 1 0 8 1 16
3 3 6 0 6 3 2 6 8 2 6 2 4 6 9 8 15
4 7 6 4 3 1 5 8 11 0 4 8 4 8 1 8 5
我發現這是在這篇文章的末尾列出一個解決辦法,但它不是在所有的「熊貓式」和容易出錯。團隊的應用或轉換功能似乎是正確的方式,但經過數小時的努力後,我仍然沒有成功。我認爲正確的方法應該是這樣的:
def func(data):
fi = data.columns[0][0]
th = data.columns[0][2]
data[(fi,'new',th)] = data[(fi,'foo',th)] + data[(fi,'bar',th)]
print data
return data
print grouped.apply(func)
新列已正確添加到函數中,但未返回。如果'新'列已經存在於df中,那麼在transform中使用相同的函數將會工作,但是如何在'動態'或分組之前在特定級別添加新列?
生成樣本DF的代碼是:
import pandas, itertools
first = ['A','B']
second = ['foo','bar','baz']
third = ['dog', 'cat']
tuples = []
for tup in itertools.product(first, second, third):
tuples.append(tup)
columns = pandas.MultiIndex.from_tuples(tuples, names=['First','Second','Third'])
data = np.random.randint(0,10,(5, 12))
df = pandas.DataFrame(data, columns=columns)
而我的解決方法:
dfnew = None
grouped = df.groupby(by=None, level=[0,2], axis=1)
for name, group in grouped:
newparam = group.xs('foo', axis=1, level=1) + group.xs('bar', axis=1, level=1)
dftmp = group.join(pandas.DataFrame(np.array(newparam), columns=pandas.MultiIndex.from_tuples([(group.columns[0][0], 'new', group.columns[0][2])], names=['First','Second', 'Third'])))
if dfnew is None:
dfnew = dftmp
else:
dfnew = pandas.concat([dfnew, dftmp], axis=1)
print dfnew.sort_index(axis=1)
至極的作品,但每個組創建一個新的數據幀和「手動」分配水平是一個非常糟糕的做法。
那麼這樣做的正確方法是什麼?我發現了幾個處理類似問題的帖子,但所有這些帖子都只有1個級別的列,這正是我正在努力的。
創建基於分組值的新列是變換任務,但我不知道如果轉換可以輸出多列。我會像你一樣解決這個問題。順便說一句,轉換也爲每個組創建一個新的框架,並在最後連接它們。 –
讓應用/變換機制能夠輸出結構化值並將這些值廣播到柱中(例如,如果元組是由應用函數生成的,則組件將在單獨的列中生成元組,而不是在單個列中成爲原子元素的元組)是一個奇妙的功能,即使它只是語法糖。可能與另一個方法名稱,使意圖清晰(applyfork或類似的東西,或關鍵字splitseq = True申請)。 – meteore