列出数据框列中相同的元素

2024-10-06 10:32:54 发布

您现在位置:Python中文网/ 问答频道 /正文

我想列举一列中出现多次的元素。不应修改只出现一次的元素

我提出了两种解决办法,但它们似乎很不雅观,我希望有更好的解决办法

Input:
   X
0  A
1  B
2  C
3  A
4  C
5  C
6  D

Output:
  new_name
X         
A       A1
A       A2
B        B
C       C1
C       C2
C       C3
D        D

这里有两种可能的方法来实现这一点,一种是使用.expanding().count(),另一种是使用.cumcount(),但两者都很难看

import pandas as pd

def solution_1(df):
    pvt = (df.groupby(by='X')
               .expanding()
               .count()
               .rename(columns={'X': 'Counter'})
               .reset_index()
               .drop('level_1', axis=1)
               .assign(name = lambda s: s['X'] + s['Counter'].astype(int).astype(str))
               .set_index('X')
               )

    pvt2 = (df.reset_index()
            .groupby(by='X')
            .count()
            .rename(columns={'index': 'C'}
            ))

    df2 = pd.merge(left=pvt, right=pvt2, left_index=True, right_index=True)

    ind=df2['C']>1
    df2.loc[ind, 'new_name']=df2.loc[ind, 'name']
    df2.loc[~ind, 'new_name']=df2.loc[~ind].index
    df2 = df2.drop(['Counter', 'C', 'name'], axis=1)

    return df2

def solution_2(df):

    pvt = pd.DataFrame(df.groupby(by='X')
                        .agg({'X': 'cumcount'})
            ).rename(columns={'X': 'Counter'})

    pvt2 = pd.DataFrame(df.groupby(by='X')
                        .agg({'X': 'count'})
            ).rename(columns={'X': 'Total Count'})
    # print(pvt2)

    df2 = df.merge(pvt, left_index=True, right_index=True)
    df3 = df2.merge(pvt2, left_on='X', right_index=True)

    ind=df3['Total Count']>1
    df3['Counter'] = df3['Counter']+1
    df3.loc[ind, 'new_name']=df3.loc[ind, 'X']+df3.loc[ind, 'Counter'].astype(int).astype(str)
    df3.loc[~ind, 'new_name']=df3.loc[~ind, 'X']
    df3 = df3.drop(['Counter', 'Total Count'], axis=1).set_index('X')
    return df3

if __name__ == '__main__':

    s = ['A', 'B', 'C', 'A', 'C', 'C', 'D']
    df = pd.DataFrame(s, columns=['X'])
    print(df)
    sol_1 = solution_1(df)
    print(sol_1)
    sol_2 = solution_2(df)
    print(sol_2)

有什么建议吗?非常感谢


Tags: columnsnametruedfnewindexcountcounter
2条回答

首先,我们使用GroupBy.cumcount来获得X中每个唯一值的累计计数

然后我们add 1并将数值转换为带有Series.astype的字符串

最后,我们用Series.cat将值合并到原始列:

df['new_name'] = df['X'].str.cat(df.groupby('X').cumcount().add(1).astype(str))

   X new_name
0  A       A1
1  A       A2
2  B       B1
3  C       C1
4  C       C2
5  C       C3
6  D       D1

如果您实际上不希望在只出现一次的值处使用数字,我们可以使用:

df['new_name'] = np.where(df.groupby('X')['X'].transform('size').eq(1), 
                          df['new_name'].str.replace('\d', ''), 
                          df['new_name'])

   X new_name
0  A       A1
1  A       A2
2  B        B
3  C       C1
4  C       C2
5  C       C3
6  D        D

一体式一行

df['new_name'] = np.where(df.groupby('X')['X'].transform('size').ne(1),
                          df['X'].str.cat(df.groupby('X').cumcount().add(1).astype(str)),
                          df['X'])

IIUC公司

df.X+(df.groupby('X').cumcount()+1).mask(df.groupby('X').X.transform('count').eq(1),'').astype(str)
Out[18]: 
0    A1
1     B
2    C1
3    A2
4    C2
5    C3
6     D
dtype: object

相关问题 更多 >