代码之家  ›  专栏  ›  技术社区  ›  singularity2047

使用python为分组数据创建新变量

  •  0
  • singularity2047  · 技术社区  · 7 年前

    我有这样一个数据框:

    d = {'name': ['john', 'john', 'john', 'Tim', 'Tim', 'Tim','Bob', 'Bob'], 'Prod': ['101', '102', '101', '501', '505', '301', '302', '302'],'Qty': ['5', '4', '1', '3', '5', '4', '1', '3']}
    df = pandas.DataFrame(data= d)
    

    enter image description here

    我想做的是,创建一个新的id变量。每当一个名字(比如john)第一次出现时,该id将等于1,对于相同名字(john)的其他出现,该id变量将为0。将对数据中的所有其他名称执行此操作。我该怎么做呢?

    最终输出应如下所示:

    enter image description here

    注意:如果有人知道SAS,您可以在那里按名称对数据进行排序,然后首先使用。名称

           ""if first.variable = 1 then id = 1""
    

    对于第一次出现的同名优先。名称=1。对于任何其他重复出现的相同名称,请先。名称=0。我试图在python中复制相同的内容。

    到目前为止,我已经尝试了pandas groupby和first()功能以及numpy。where()但无法实现任何功能。如有任何新观点,将不胜感激。

    2 回复  |  直到 7 年前
        1
  •  3
  •   BENY    7 年前

    您可以使用 cumcount

    s=df.groupby(['Prod','name']).cumcount().add(1)
    df['counter']=s.mask(s.gt(1),0)
    df
    Out[1417]: 
      Prod Qty  name  counter
    0  101   5  john        1
    1  102   4  john        1
    2  101   1  john        0
    3  501   3   Tim        1
    4  505   5   Tim        1
    5  301   4   Tim        1
    6  302   1   Bob        1
    7  302   3   Bob        0
    

    更新时间:

    s=df.groupby(['name']).cumcount().add(1).le(1).astype(int)
    s
    Out[1421]: 
    0    1
    1    0
    2    0
    3    1
    4    0
    5    0
    6    1
    7    0
    dtype: int32
    

    更快

    df.loc[df.name.drop_duplicates().index,'counter']=1
    df.fillna(0)
    Out[1430]: 
      Prod Qty  name  counter
    0  101   5  john      1.0
    1  102   4  john      0.0
    2  101   1  john      0.0
    3  501   3   Tim      1.0
    4  505   5   Tim      0.0
    5  301   4   Tim      0.0
    6  302   1   Bob      1.0
    7  302   3   Bob      0.0
    
        2
  •  1
  •   Primusa    7 年前

    我们可以直接使用字典d并循环创建新条目。

    d = {'name': ['john', 'john', 'john', 'Tim', 'Tim', 'Tim','Bob', 'Bob'], 'Prod': ['101', '102', '101', '501', '505', '301', '302', '302'],'Qty': ['5', '4', '1', '3', '5', '4', '1', '3']}
    names = set() #store names that have appeared
    id = []
    for i in d['name']:
        if i in names: #if it appeared add 0
             id.append(0)
        else:
             id.append(1) #add 1 and note that it has appeared
             names.add(i)
    d['id'] = id #add entry to your dictionary
    df = pandas.DataFrame(data= d)