4

我有一个 pandas 数据框,我想创建一个新列,该列对不同的行组进行不同的计算。这是一个简单的例子:

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')两次(就像我现在做的那样)?
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 回答