import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
data={'state':[1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4],
'year':[1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3],
'pop':[11, 22, 0, 33, 44, 32, 45, 66, 34, 12, 32, 0],
'gdp':[123, 341, 554, 654, 245, 665, 332 ,321, 344, 232, 542, 221]}
frame=pd.DataFrame(data)
def treat(group):
if group.ix[group.year==3, 'pop']!=0:
group['Treated']=1
else:
group['Treated']=0
frame.groupby('state').apply(treat)
我正在尝试根据某些条件创建变量frame['Treated']
。
if ('year'==3) and ('pop'!=0)
- 我认为'州'在Treated组中(因此我创建了一个名为' Treated'的变量)。
不幸的是我最终得到了一个错误:
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
我的代码出了什么问题?你知道我怎么能解决这个问题吗?
重新编辑 感谢您的回答,我很抱歉没有清楚地描述我的问题。
我试图再次描述我的问题。 对于状态1,pop 3在第3年为0,因此状态1不在处理组中(如下所示,框架[' Treated'] = 0表示每年的状态1) 对于状态2,pop 3在第3年不等于0,因此状态2在处理组中(如下所示,框架[' Treated'] = 1表示每年的状态2) 其他州因类似原因而被处理。 最终结果如下。
state year pop gdp Treated
0 1 1 11 123 0
1 1 2 22 341 0
2 1 3 0 554 0
3 2 1 33 654 1
4 2 2 44 245 1
5 2 3 32 665 1
6 3 1 45 332 1
7 3 2 66 321 1
8 3 3 34 344 1
9 4 1 12 232 0
10 4 2 32 542 0
11 4 3 0 221 0
答案 0 :(得分:4)
groupby
,您只需要np.where
frame['Treated']=np.where((frame.year==3)&(frame.pop!=0),1,0)
frame
Out[429]:
gdp pop state year Treated
0 123 11 1 1 0
1 341 22 1 2 0
2 554 0 1 3 1
3 654 33 2 1 0
4 245 44 2 2 0
5 665 32 2 3 1
6 332 45 3 1 0
7 321 66 3 2 0
8 344 34 3 3 1
9 232 12 4 1 0
10 542 32 4 2 0
11 221 0 4 3 1
答案 1 :(得分:0)
np.where
的替代方法是将适当的布尔掩码转换为整数类型。
frame['Treated'] = (frame.year.eq(3) & frame['pop'].ne(0)).astype(int)
您当前的代码无效,因为
group.ix[group.year==3, 'pop']!=0
还有一个Pandas系列,你不能在if语句中安全地使用它。在任何情况下,当您使用布尔掩码解决问题时,使用这样的apply
是不好的形式。
答案 2 :(得分:0)
使用pandas.DataFrame.assign
和pandas.DataFrame.eval
frame.assign(Treated=frame.eval('pop != 0 & year == 3') * 1)
gdp pop state year Treated
0 123 11 1 1 0
1 341 22 1 2 0
2 554 0 1 3 0
3 654 33 2 1 0
4 245 44 2 2 0
5 665 32 2 3 1
6 332 45 3 1 0
7 321 66 3 2 0
8 344 34 3 3 1
9 232 12 4 1 0
10 542 32 4 2 0
11 221 0 4 3 0
我乘以1来强制整数。它是较短的代码,但不如@miradulo的astype(int)