2016-08-12 90 views
3

我有一个数据帧熊猫柱的,其一个的的.loc函数为:使用大熊猫数据帧

a = [1,0,1,0,1,3,4,6,4,6] 

现在我想创建另一列,使得大于0且小于5的任何值是分配1,将其余的分配0,即:

a = [1,0,1,0,1,3,4,6,4,6] 
b = [1,0,1,0,1,1,1,0,1,0] 

现在我已经做到了这一点

dtaframe['b'] = dtaframe['a'].loc[0 < dtaframe['a'] < 5] = 1 
dtaframe['b'] = dtaframe['a'].loc[dtaframe['a'] >4 or dtaframe['a']==0] = 0 

但码T徘徊和错误。该怎么办 ?

回答

2

当使用比较运算符和布尔逻辑来过滤数据框时,不能使用a < myseries < b的pythonic惯用语。相反,你需要(a < myseries) & (myseries < b)

cond1 = (0 < dtaframe['a']) 
cond2 = (dtaframe['a'] <= 5) 
dtaframe['b'] = (cond1 & cond2) * 1 
+1

我昨天了解它,也有'myseries.between( a,b)'([docs](http://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.between.html)) – ayhan

+1

@ayhan我也想包括: - ) – piRSquared

+0

@piRSquared它似乎在抛出一些错误或:('ValueError:一个Series的真值不明确。使用a.empty,a.bool(),a.item(),a.any()或a.all()'。 –

4

您可以使用between获得布尔值,然后astype从布尔值转换为0/1:

dtaframe['b'] = dtaframe['a'].between(0, 5, inclusive=False).astype(int) 

输出结果:

a b 
0 1 1 
1 0 0 
2 1 1 
3 0 0 
4 1 1 
5 3 1 
6 4 1 
7 6 0 
8 4 1 
9 6 0 

编辑

对于多个范围,你可以使用pandas.cut

dtaframe['b'] = pd.cut(dtaframe['a'], bins=[0,1,6,9], labels=False, include_lowest=True) 

你需要小心你如何定义bins。使用labels=False将返回每个bin的整数指示符,它恰好与您提供的标签相对应。您还可以手动指定每个垃圾箱的标签,例如labels=[0,1,2],labels=[0,17,19],labels=['a','b','c']等。如果您手动指定标签,则可能需要使用astype,因为它们将作为类别返回。

或者,你可以结合locbetween手动指定每个范围:

dtaframe.loc[dtaframe['a'].between(0,1), 'b'] = 0 
dtaframe.loc[dtaframe['a'].between(2,6), 'b'] = 1 
dtaframe.loc[dtaframe['a'].between(7,9), 'b'] = 2 
+0

你打我吧 – piRSquared

+0

@root辉煌的答案:)如果我必须做3班。如从0-1分配0,2-6分配1,最后从7-9分配3。谢谢你的回答 –

+0

@AuuragPandey:我已经做了一个编辑来解决多个范围。尽管如此,您可能希望将其作为一个单独的问题,以获得更多的意见。我的方法可能不是最佳的。 – root

1

np.where试试这个:

dtaframe['b'] = np.where(([dtaframe['a'] > 4) | (dtaframe['a']==0),0, dtaframe['a'])