首页 > 解决方案 > 如果组中的任何一行包含某个值,则创建一个新列并分配值

问题描述

我正在尝试根据以下原则为 group by 中的每个组分配一个新列:如果组中的任何一行包含特定值,则该组的新列值应该是某个值。

到目前为止,我已经尝试使用 np.where 和 pandas 数据框 any() 并将其应用于分组依据。这适用于非常小的数据集。我的原始数据集包含大约 180 万条记录,我尝试过的方法太慢,它永远不会在原始数据集上运行完成。所以想知道是否有一种有效的方法来实现这一点。

例如,如果我有一个包含 A、B 和 C 列的数据框

     A      B   C
0   alpha   m   t
1   beta    n   r
2   cosine  q   f
3   alpha   m   t
4   beta    m   t
5   alpha   n   r
6   cosine  q   f

对于 B 和 C 组,创建一个新列“D”,其值基于“A”。在一个组中,如果 A 列的任何一行具有 beta,则该组的“D”列(D 的所有行)应该是 beta。如果组中没有任何行包含 beta,则下一个层次结构是余弦,即,如果该组中 A 列的任何行具有余弦,则该组中 D 列的所有行都应该是余弦。

到目前为止我尝试过的方法:

def test(dft):
    dft['D']=np.where(dft[dft['A']=='beta'].any(),'beta',np.where(dft[dft['A']=='cosine'].any(),'cosine',np.where(dft[dft['A']=='alpha'].any(),'alpha',dft['A'])))
    return dft['D']
dft2=dft.groupby(['B','C']).apply(test)
dft2=dft2.reset_index()

我得到的结果是:

    B   C   level_2    D
0   m   t   0         beta
1   m   t   3         beta
2   m   t   4         beta
3   n   r   1         beta
4   n   r   5         beta
5   q   f   2         cosine
6   q   f   6         cosine

预期结果应如下所示:

     A      B   C          D
0   alpha   m   t        beta
1   beta    n   r        beta
2   cosine  q   f        cosine
3   alpha   m   t        beta
4   beta    m   t        beta
5   alpha   n   r        beta
6   cosine  q   f        cosine

标签: pythonpandaspandas-groupby

解决方案


IIUC 使用Categorical转换您的列 A ,然后执行groupby transform

df.A=pd.Categorical(df.A,categories=['alpha','cosine','beta'],ordered=True)
df.groupby(['B','C']).A.transform('max')
Out[1200]: 
0      beta
1      beta
2    cosine
3      beta
4      beta
5      beta
6    cosine
Name: A, dtype: object
df['D']=df.groupby(['B','C']).A.transform('max')

推荐阅读