Python 枚举dataframe列中的相等元素

Python 枚举dataframe列中的相等元素,python,pandas,Python,Pandas,我想列举一列中多次出现的元素。不应修改仅出现一次的图元 我提出了两个解决方案,但它们似乎非常不雅观,我希望有更好的解决方案 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 这里有两种可能的实现方法,一种是使用.expansing().c

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

我提出了两个解决方案,但它们似乎非常不雅观,我希望有更好的解决方案

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
这里有两种可能的实现方法,一种是使用
.expansing().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)


有什么建议吗?非常感谢。

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

然后我们
添加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'])

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

然后我们
添加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

IIUC

pd.DataFrame(df['X'].value_counts())
作为备选方案?
pd.DataFrame(df['X'].value_counts())
作为备选方案?