4

パンダのデータフレームがあり、行のグループごとに異なる方法で計算される新しい列を作成したいと考えています。簡単な例を次に示します。

import pandas as pd

data = {'foo': list('aaade'), 'bar': range(5)}
df = pd.DataFrame(data)

データフレームは次のようになります。

     bar foo
0    0   a
1    1   a
2    2   a
3    3   d
4    4   e

今、新しい列を追加して、選択した行にいくつかの値を割り当てようとしています:

df['xyz'] = 0
df.loc[(df['foo'] == 'a'), 'xyz'] = df.loc[(df['foo'] == 'a')].apply(lambda x: x['bar'] * 2, axis=1)

データフレームは変更されていません。私が期待するのは、データフレームが次のようになることです。

     bar foo  xyz
0    0   a    0
1    1   a    2
2    2   a    4
3    3   d    0
4    4   e    0

私の現実の問題では、「xyz」列も他の行に対して計算されますが、別の関数を使用しています。実際、計算には別の列も使用しています。だから私の質問:

  1. 上記の例の割り当てが機能しないのはなぜですか?
  2. df.loc[(df['foo'] == 'a')(私が今やっているように)2回行う必要がありますか?
4

1 に答える 1

3

df のコピーを変更しています (DataFrame のブール値マスクはコピーです。 docsを参照してください)。
目的の結果を達成する別の方法は次のとおりです。

In [11]: df.apply(lambda row: (row['bar']*2 if row['foo'] == 'a' else row['xyz']), axis=1)
Out[11]:
0    0
1    2
2    4
3    0
4    0
dtype: int64

In [12]: df['xyz'] = df.apply(lambda row: (row['bar']*2 if row['foo'] == 'a' else row['xyz']), axis=1)

In [13]: df
Out[13]:
   bar foo  xyz
0    0   a    0
1    1   a    2
2    2   a    4
3    3   d    0
4    4   e    0

おそらく、よりきちんとした方法は次のとおりです。

In [21]: 2 * (df1.bar) * (df1.foo == 'a')
Out[21]:
0    0
1    2
2    4
3    0
4    0
dtype: int64
于 2013-05-22T11:00:06.253 に答える