【问题标题】:How can I apply function to create dummy variable?如何应用函数来创建虚拟变量?
【发布时间】:2018-10-10 02:52:02
【问题描述】:
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) - 我认为 'state' 在 Treated 组中(所以我创建了一个名为 'Treated' 的变量)。

不幸的是,我遇到了一个错误:

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

我的代码有什么问题?你知道我该如何解决这个问题吗?

重新编辑 感谢您的友好回答,很抱歉没有清楚地描述我的问题。

我正在尝试再次描述我的问题。 对于状态 1 ,第 3 年的 pop 为 0 ,因此状态 1 不在处理组中(如下所示,每年状态 1 的 frame['Treated']=0 ) 对于状态2,在第3年pop不等于0,所以状态2在处理组中(如下图,对于状态2,每一年frame['Treated']=1) 出于类似原因处理其他状态。 最终结果如下。

    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

【问题讨论】:

    标签: python python-3.x pandas apply pandas-groupby


    【解决方案1】:

    使用pandas.DataFrame.assignpandas.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
    

    我乘以一来强制一个整数。它的代码更短,但效率不如@miradulo 的astype(int)

    【讨论】:

      【解决方案2】:

      np.where 的替代方法是将适当的布尔掩码转换为整数类型。

      frame['Treated'] = (frame.year.eq(3) & frame['pop'].ne(0)).astype(int)
      

      您当前的代码不起作用,因为

      group.ix[group.year==3, 'pop']!=0
      

      仍然为您留下 Pandas 系列,您不能在 if 语句中安全地使用它。在任何情况下,当您可以使用布尔掩码解决问题时,像这样使用 apply 是不好的形式。

      【讨论】:

        【解决方案3】:

        这里不需要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
        

        【讨论】:

        • frame.pop 是一种方法,当然不等于0,因此总是True。索引为2 的行不应为1。你想要np.where((frame.year == 3) & (frame['pop'] != 0), 1, 0)
        • @piRSquared 是的,这是真的,因为 pop 是函数名,谢谢您的先生
        猜你喜欢
        • 2015-01-29
        • 2012-09-27
        • 1970-01-01
        • 2020-11-22
        • 2023-03-27
        • 2018-04-06
        • 2020-01-31
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多