上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
だから、3列のレベルがあります。私は第2レベルに新しい列を追加して、第3レベルのそれぞれに対して計算が行われるようにしたいとします。たとえば、 '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)
新しい列は関数内に正しく追加されていますが返されません。変換で同じ関数を使用すると、 'new'列がすでにdfに存在する場合でも、 'オンザフライで'特定のレベルで、またはグループ化する前に、新しい列を追加する方法はありますか?
サンプル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)
WICHは動作しますが、各グループの新しいデータフレームを作成し、「手動」のレベルを割り当てることです本当に悪い習慣。
これを行う適切な方法は何ですか?私は同様の質問を扱ういくつかの記事を見つけましたが、これらのすべてには1つのレベルのカラムしかありませんでした。
グループ化された値に基づいて新しい列を作成すると、変換のための作業ですしかし、tranformが複数の列を出力できるかどうかは分かりません。あなたと同じ方法でこれに取り組んでいきます。ボンネットの下にあるBTWでは、トランスフォームによってグループごとに新しいフレームが作成され、最後にすべて連結されます。 –
適用/変換メカニズムで構造化された値とブロードキャストを列に出力できます(つまり、適用された関数によってタプルが生成された場合、タプルが単一の列のアトム要素になるのではなく別々の列に入ります)。それが構文的な砂糖だけであっても、素晴らしい機能になります。おそらく別のメソッド名を使って、意図を明確にする(applyforkかそのようなもの、またはキーワードsplitseq = Trueを適用する)。 – meteore