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())
作为备选方案?