每个唯一 ID 的每一行中最常用的描述
Most commonly used description use in each row for each unique id
我有问题。我有文章,这些文章有一个独特的 id
。然而,问题是 article
描述又名 article
- 这不是唯一的。
我想尝试更改 article
描述 article
的名称,以便只剩下一个描述。我总是想使用最常出现的 article
名称。
我已经尝试了一些东西,但是我不知道如何使用 .apply(lambda x: ...
访问它并将最常用的项目写给我,然后将其设置为名称。
如何更改文章的描述,以便仅包含最常提及的文章描述?
id article cost
0 1 Bendge 15.30
1 1 Bendge 15.30
2 1 Bendge V2 15.30
3 1 Bendge - volumne 2 15.30
4 5 SEF 14.89
5 1 Bendge 15.30
6 2 DFH 4.56
7 2 DFH 4.56
8 2 DFH V2 4.56
9 2 DFH - volumne 2 4.56
10 2 DFH 4.56
代码
d = {'id': [1, 1, 1, 1, 5, 1, 2, 2, 2, 2, 2],
'article': ['Bendge', 'Bendge', 'Bendge V2', 'Bendge - volumne 2', 'SEF', 'Bendge',
'DFH', 'DFH', 'DFH V2', 'DFH - volumne 2', 'DFH'],
'cost': [15.30, 15.30, 15.30, 15.30, 14.89, 15.30,
4.56, 4.56, 4.56, 4.56, 4.56],
}
df = pd.DataFrame(data=d)
display(df)
df.loc[df['id'] == 1, ['id','article']].value_counts().head(1)
[OUT]
id article
1 Bendge 3
dtype: int64
df['article'] = df.apply(lambda x: x[['id','article']].value_counts().head(1))
[OUT]
KeyError: "None of [Index(['id', 'article'], dtype='object')] are in the [index]"
我想要的
id article cost
0 1 Bendge 15.30
1 1 Bendge 15.30
2 1 Bendge 15.30
3 1 Bendge 15.30
4 5 SEF 14.89
5 1 Bendge 15.30
6 2 DFH 4.56
7 2 DFH 4.56
8 2 DFH 4.56
9 2 DFH 4.56
10 2 DFH 4.56
使用GroupBy.transform
with lambda function with Series.value_counts
和第一个索引:
df['article'] = df.groupby('id')['article'].transform(lambda x: x.value_counts().index[0])
print (df)
id article cost
0 1 Bendge 15.30
1 1 Bendge 15.30
2 1 Bendge 15.30
3 1 Bendge 15.30
4 5 SEF 14.89
5 1 Bendge 15.30
6 2 DFH 4.56
7 2 DFH 4.56
8 2 DFH 4.56
9 2 DFH 4.56
10 2 DFH 4.56
第一个值为 Series.mode
的另一个解决方案:
df['article'] = df.groupby('id')['article'].transform(lambda x: x.mode().iat[0])
print (df)
id article cost
0 1 Bendge 15.30
1 1 Bendge 15.30
2 1 Bendge 15.30
3 1 Bendge 15.30
4 5 SEF 14.89
5 1 Bendge 15.30
6 2 DFH 4.56
7 2 DFH 4.56
8 2 DFH 4.56
9 2 DFH 4.56
10 2 DFH 4.56
您可以使用 value_counts
来获取计数; reset_index
+ pivot
+ idxmax
得到每个 id
最常见的 article
;然后 map
回到 id
:
mapping = df.value_counts(['id','article']).reset_index().pivot('id','article', 0).idxmax(axis=1)
df['article'] = df['id'].map(mapping)
输出:
id article cost
0 1 Bendge 15.30
1 1 Bendge 15.30
2 1 Bendge 15.30
3 1 Bendge 15.30
4 5 SEF 14.89
5 1 Bendge 15.30
6 2 DFH 4.56
7 2 DFH 4.56
8 2 DFH 4.56
9 2 DFH 4.56
10 2 DFH 4.56
您可以使用 mode
:
df['article'] = df['id'].map(df.groupby('id')['article'].agg(pd.Series.mode))
或者如果有平局的可能性:
df['article'] = df['id'].map(df.groupby('id')['article'].agg(lambda s: s.mode(s).iloc[0]))
输出:
id article cost
0 1 Bendge 15.30
1 1 Bendge 15.30
2 1 Bendge 15.30
3 1 Bendge 15.30
4 5 SEF 14.89
5 1 Bendge 15.30
6 2 DFH 4.56
7 2 DFH 4.56
8 2 DFH 4.56
9 2 DFH 4.56
10 2 DFH 4.56
使用:
#preparing data
string = """ c id article cost
0 1 Bendge 15.30
1 1 Bendge 15.30
2 1 BendgeV2 15.30
3 1 Bendge-volumne2 15.30
4 5 SEF 14.89
5 1 Bendge 15.30
6 2 DFH 4.56
7 2 DFH 4.56
8 2 DFHV2 4.56
9 2 DFH-volumne2 4.56
10 2 DFH 4.56"""
data = [x.split() for x in string.split('\n')]
import pandas as pd
df = pd.DataFrame(data[1:], columns = data[0])
#solution
df['article'] = df.groupby('id')['article'].transform(lambda x: x.value_counts().index[0])
输出:
c id article cost
0 0 1 Bendge 15.30
1 1 1 Bendge 15.30
2 2 1 Bendge 15.30
3 3 1 Bendge 15.30
4 4 5 SEF 14.89
5 5 1 Bendge 15.30
6 6 2 DFH 4.56
7 7 2 DFH 4.56
8 8 2 DFH 4.56
9 9 2 DFH 4.56
10 10 2 DFH 4.56
第二种解决方案:
from collections import Counter
df.groupby('id')['article'].transform(lambda x: Counter(x).most_common()[0][0])
我有问题。我有文章,这些文章有一个独特的 id
。然而,问题是 article
描述又名 article
- 这不是唯一的。
我想尝试更改 article
描述 article
的名称,以便只剩下一个描述。我总是想使用最常出现的 article
名称。
我已经尝试了一些东西,但是我不知道如何使用 .apply(lambda x: ...
访问它并将最常用的项目写给我,然后将其设置为名称。
如何更改文章的描述,以便仅包含最常提及的文章描述?
id article cost
0 1 Bendge 15.30
1 1 Bendge 15.30
2 1 Bendge V2 15.30
3 1 Bendge - volumne 2 15.30
4 5 SEF 14.89
5 1 Bendge 15.30
6 2 DFH 4.56
7 2 DFH 4.56
8 2 DFH V2 4.56
9 2 DFH - volumne 2 4.56
10 2 DFH 4.56
代码
d = {'id': [1, 1, 1, 1, 5, 1, 2, 2, 2, 2, 2],
'article': ['Bendge', 'Bendge', 'Bendge V2', 'Bendge - volumne 2', 'SEF', 'Bendge',
'DFH', 'DFH', 'DFH V2', 'DFH - volumne 2', 'DFH'],
'cost': [15.30, 15.30, 15.30, 15.30, 14.89, 15.30,
4.56, 4.56, 4.56, 4.56, 4.56],
}
df = pd.DataFrame(data=d)
display(df)
df.loc[df['id'] == 1, ['id','article']].value_counts().head(1)
[OUT]
id article
1 Bendge 3
dtype: int64
df['article'] = df.apply(lambda x: x[['id','article']].value_counts().head(1))
[OUT]
KeyError: "None of [Index(['id', 'article'], dtype='object')] are in the [index]"
我想要的
id article cost
0 1 Bendge 15.30
1 1 Bendge 15.30
2 1 Bendge 15.30
3 1 Bendge 15.30
4 5 SEF 14.89
5 1 Bendge 15.30
6 2 DFH 4.56
7 2 DFH 4.56
8 2 DFH 4.56
9 2 DFH 4.56
10 2 DFH 4.56
使用GroupBy.transform
with lambda function with Series.value_counts
和第一个索引:
df['article'] = df.groupby('id')['article'].transform(lambda x: x.value_counts().index[0])
print (df)
id article cost
0 1 Bendge 15.30
1 1 Bendge 15.30
2 1 Bendge 15.30
3 1 Bendge 15.30
4 5 SEF 14.89
5 1 Bendge 15.30
6 2 DFH 4.56
7 2 DFH 4.56
8 2 DFH 4.56
9 2 DFH 4.56
10 2 DFH 4.56
第一个值为 Series.mode
的另一个解决方案:
df['article'] = df.groupby('id')['article'].transform(lambda x: x.mode().iat[0])
print (df)
id article cost
0 1 Bendge 15.30
1 1 Bendge 15.30
2 1 Bendge 15.30
3 1 Bendge 15.30
4 5 SEF 14.89
5 1 Bendge 15.30
6 2 DFH 4.56
7 2 DFH 4.56
8 2 DFH 4.56
9 2 DFH 4.56
10 2 DFH 4.56
您可以使用 value_counts
来获取计数; reset_index
+ pivot
+ idxmax
得到每个 id
最常见的 article
;然后 map
回到 id
:
mapping = df.value_counts(['id','article']).reset_index().pivot('id','article', 0).idxmax(axis=1)
df['article'] = df['id'].map(mapping)
输出:
id article cost
0 1 Bendge 15.30
1 1 Bendge 15.30
2 1 Bendge 15.30
3 1 Bendge 15.30
4 5 SEF 14.89
5 1 Bendge 15.30
6 2 DFH 4.56
7 2 DFH 4.56
8 2 DFH 4.56
9 2 DFH 4.56
10 2 DFH 4.56
您可以使用 mode
:
df['article'] = df['id'].map(df.groupby('id')['article'].agg(pd.Series.mode))
或者如果有平局的可能性:
df['article'] = df['id'].map(df.groupby('id')['article'].agg(lambda s: s.mode(s).iloc[0]))
输出:
id article cost
0 1 Bendge 15.30
1 1 Bendge 15.30
2 1 Bendge 15.30
3 1 Bendge 15.30
4 5 SEF 14.89
5 1 Bendge 15.30
6 2 DFH 4.56
7 2 DFH 4.56
8 2 DFH 4.56
9 2 DFH 4.56
10 2 DFH 4.56
使用:
#preparing data
string = """ c id article cost
0 1 Bendge 15.30
1 1 Bendge 15.30
2 1 BendgeV2 15.30
3 1 Bendge-volumne2 15.30
4 5 SEF 14.89
5 1 Bendge 15.30
6 2 DFH 4.56
7 2 DFH 4.56
8 2 DFHV2 4.56
9 2 DFH-volumne2 4.56
10 2 DFH 4.56"""
data = [x.split() for x in string.split('\n')]
import pandas as pd
df = pd.DataFrame(data[1:], columns = data[0])
#solution
df['article'] = df.groupby('id')['article'].transform(lambda x: x.value_counts().index[0])
输出:
c id article cost
0 0 1 Bendge 15.30
1 1 1 Bendge 15.30
2 2 1 Bendge 15.30
3 3 1 Bendge 15.30
4 4 5 SEF 14.89
5 5 1 Bendge 15.30
6 6 2 DFH 4.56
7 7 2 DFH 4.56
8 8 2 DFH 4.56
9 9 2 DFH 4.56
10 10 2 DFH 4.56
第二种解决方案:
from collections import Counter
df.groupby('id')['article'].transform(lambda x: Counter(x).most_common()[0][0])