2013-05-22 63 views
3

我有一个熊猫数据框,我想要创建一个新的列,对于不同的行组进行不同的计算。下面是一个简单的例子:分配到熊猫中的选择

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”列也computated对于其他行,但使用不同的功能。实际上,我也在使用不同的列进行计算。所以我的问题:

  1. 为什么上述例子中的赋值不起作用?
  2. 是否需要两次做df.loc[(df['foo'] == 'a')(正如我现在这样做)?

回答

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 
+0

是,杰夫,写更多的东西来的文档是我的待办事项列表。 :) –

+0

,我甚至没有评论:) – Jeff

+0

感谢您的快速回答。这正是我想要的。如果有其他呼叫,可以将这些链接起来吗? – uuazed