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

np.当索引大于某个值时

  •  1
  • rahlf23  · 技术社区  · 6 年前

    我以为这是相当直截了当的,但很明显我这里遗漏了一些东西。

    我想利用 np.where 具有 df.groupby('Name').apply() 在中创建新列 df (叫它 'New' ,其中列的值是 1 如果各组的指数(与原始指数相对应的指数 测向 )大于或等于( >= )一个特定的值,否则 0 .

    作为背景,我正在分组 测向 'Name' 柱和我有一个 dict() 其中包含要用于 groupby() .我希望这是明确的,我可以提供进一步的澄清,如果必要的话。

    这是我到目前为止的样品 测向 以下内容:

    df = pd.DataFrame([['William', 1, 0, 0, 0, 1],['James', 0, 1, 1, 1, 1],['James', 1, 0, 0, 0, 0],
                    ['James', 1, 0, 1, 1, 0],['William', 0, 1, 1, 0, 1],['William', 0, 0, 0, 0, 0],
                    ['William', 1, 0, 1, 1, 0],['James', 0, 1, 1, 0, 1],['James', 0, 0, 0, 0, 0]],
                    columns=['Name','x1','x2','x3','x4','Interest'])
    
           Name  x1  x2  x3  x4  Interest
    0  William   1   0   0   0         1
    1    James   0   1   1   1         1
    2    James   1   0   0   0         0
    3    James   1   0   1   1         0
    4  William   0   1   1   0         1
    5  William   0   0   0   0         0
    6  William   1   0   1   1         0
    7    James   0   1   1   0         1
    8    James   0   0   0   0         0
    

    然后我找到最后一排 测向 对于每个组, 'Interest' 列有一个 1个 ,使用:

    mydict = df[df['Interest']==1].groupby('Name').apply(lambda x: x.index[-1]).to_dict()
    
    {'James': 7, 'William': 4}
    

    注意:这是一个简化的例子。对于我的实际应用,我将把第3行的索引拉到最后一行(即 .apply(lambda x: x.index[-3]).to_dict() 然而,下一部分是我问题的根源所在。

    现在,我想创建一个新列 '名称' ,其中值为 1个 如果行索引是 >= 价值 mydict 对于那个组,否则 0 .我试过几件事:

    for key, val in mydict.items():
        df['New'] = np.where((df['Name']==key) & (df.index>=val), 1, 0)
    

    这显然会覆盖为 'James' 只需返回正确的列 'William' .我怎样才能有效地做到这一点?

    要彻底了解,这里是我的预期输出:

          Name  x1  x2  x3  x4  Interest  New
    0  William   1   0   0   0         1    0
    1    James   0   1   1   1         1    0
    2    James   1   0   0   0         0    0
    3    James   1   0   1   1         0    0
    4  William   0   1   1   0         1    1
    5  William   0   0   0   0         0    1
    6  William   1   0   1   1         0    1
    7    James   0   1   1   0         1    1
    8    James   0   0   0   0         0    1
    
    2 回复  |  直到 6 年前
        1
  •  3
  •   piRSquared    6 年前

    使用 map

    df.assign(New=(df.index >= df.Name.map(mydict)).astype(int))
    
          Name  x1  x2  x3  x4  Interest  New
    0  William   1   0   0   0         1    0
    1    James   0   1   1   1         1    0
    2    James   1   0   0   0         0    0
    3    James   1   0   1   1         0    0
    4  William   0   1   1   0         1    1
    5  William   0   0   0   0         0    1
    6  William   1   0   1   1         0    1
    7    James   0   1   1   0         1    1
    8    James   0   0   0   0         0    1
    
        2
  •  2
  •   jezrael    6 年前

    reduce True 1 S:

    m = [((df['Name']==key) & (df.index>=val)) for key, val in mydict.items()]
    print (m)
    [0    False
    1    False
    2    False
    3    False
    4    False
    5    False
    6    False
    7     True
    8     True
    Name: Name, dtype: bool, 0    False
    1    False
    2    False
    3    False
    4     True
    5     True
    6     True
    7    False
    8    False
    Name: Name, dtype: bool]
    
    df['New'] = np.logical_or.reduce(m).astype(int)
    print (df)
          Name  x1  x2  x3  x4  Interest  New
    0  William   1   0   0   0         1    0
    1    James   0   1   1   1         1    0
    2    James   1   0   0   0         0    0
    3    James   1   0   1   1         0    0
    4  William   0   1   1   0         1    1
    5  William   0   0   0   0         0    1
    6  William   1   0   1   1         0    1
    7    James   0   1   1   0         1    1
    8    James   0   0   0   0         0    1
    

    df = pd.concat([df] * 2, ignore_index=True)
    

    idx = df[df['Interest']==1].groupby('Name').cumcount(ascending=False).eq(2).idxmax()
    

    将IDX到END的值设置为1:

    df['New'] = 0
    df.loc[idx:, 'New'] = 1
    print (df)
           Name  x1  x2  x3  x4  Interest  New
    0   William   1   0   0   0         1    0
    1     James   0   1   1   1         1    0
    2     James   1   0   0   0         0    0
    3     James   1   0   1   1         0    0
    4   William   0   1   1   0         1    1
    5   William   0   0   0   0         0    1
    6   William   1   0   1   1         0    1
    7     James   0   1   1   0         1    1
    8     James   0   0   0   0         0    1
    9   William   1   0   0   0         1    1
    10    James   0   1   1   1         1    1
    11    James   1   0   0   0         0    1
    12    James   1   0   1   1         0    1
    13  William   0   1   1   0         1    1
    14  William   0   0   0   0         0    1
    15  William   1   0   1   1         0    1
    16    James   0   1   1   0         1    1
    17    James   0   0   0   0         0    1
    

    print (df[df['Interest']==1].groupby('Name').cumcount(ascending=False))
    0     3
    1     3
    4     2
    7     2
    9     1
    10    1
    13    0
    16    0
    dtype: int64