Skip to main content
 首页 » 编程设计

python之np.where 索引大于某个值

2025年05月04日21me-sa

我原以为这会相当简单,但显然我在这里遗漏了一些东西。

我希望能够利用 np.where 和 df.groupby('Name').apply() 在 df 中创建一个新列(称之为 'New'),如果相应组的索引(对应于原始 的索引),则该列的值为 1 df) 大于或等于 (>=) 特定值,否则 0。

作为背景,我按 'Name' 列对 df 进行分组,并且我有一个包含相应值的 dict()用于 groupby() 中的每个名称。我希望这很清楚,如有必要,我可以提供进一步的说明。

这是我到目前为止所拥有的,给定示例 df:

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 

然后我在 df 中为 '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()),但是下一部分是我的问题的根源在哪里。

现在,我想创建一个新列 'Name',如果行索引为 >=,则该列的值为 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 

请您参考如下方法:

使用 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