Python 在两个值之间进行选择,并设置数据帧中最频繁的值
我最近问了一个问题,但现在我有一个新问题。这是我的数据框:Python 在两个值之间进行选择,并设置数据帧中最频繁的值,python,pandas,dataframe,Python,Pandas,Dataframe,我最近问了一个问题,但现在我有一个新问题。这是我的数据框: df = pd.DataFrame({'id':[1,1,1,1,2,2,2,3,3,3,4,4], 'sex': [0,0,0,1,0,0,0,1,1,0,1,1]}) id sex 0 1 0 1 1 0 2 1 0 3 1 1 4 2 0 5 2 0 6 2 0 7 3 1 8 3 1 9 3 0 10 4
df = pd.DataFrame({'id':[1,1,1,1,2,2,2,3,3,3,4,4],
'sex': [0,0,0,1,0,0,0,1,1,0,1,1]})
id sex
0 1 0
1 1 0
2 1 0
3 1 1
4 2 0
5 2 0
6 2 0
7 3 1
8 3 1
9 3 0
10 4 1
11 4 1
现在我需要为混合性别值的id设置性别值。它应该是最常见的值。所以我想得到这样的东西:
id sex
0 1 0
1 1 0
2 1 0
3 1 0
4 2 0
5 2 0
6 2 0
7 3 1
8 3 1
9 3 1
10 4 1
11 4 1
在那之后,我只想得到一对身份证-性伴侣:
id sex
0 1 0
1 2 0
2 3 1
3 4 1
选项1
您可以使用
groupby
后跟value\u counts
和idxmax
df = df.set_index('id').groupby(level=0).sex\
.apply(lambda x: x.value_counts().idxmax()).reset_index()
df
id sex
0 1 0
1 2 0
2 3 1
3 4 1
选项2
与选项1类似,但分两步,使用
drop\u duplicates
df.sex = df.groupby('id').sex.transform(lambda x: x.value_counts().idxmax())
df
id sex
0 1 0
1 1 0
2 1 0
3 1 0
4 2 0
5 2 0
6 2 0
7 3 1
8 3 1
9 3 1
10 4 1
11 4 1
df = df.drop_duplicates()
df
id sex
0 1 0
4 2 0
7 3 1
10 4 1
使用默认排序,因此[0]
只需选择第一个索引:
df = df.groupby('id')['sex'].apply(lambda x: x.value_counts().index[0]).reset_index()
print (df)
id sex
0 1 0
1 2 0
2 3 1
3 4 1
您也可以使用
np.bincount
In [179]: df.groupby('id')['sex'].apply(lambda x: np.argmax(np.bincount(x))).reset_index()
Out[179]:
id sex
0 1 0
1 2 0
2 3 1
3 4 1
时间安排
In [194]: df = pd.concat([df]*1000, ignore_index=True)
In [195]: df.shape
Out[195]: (12000, 2)
In [196]: %timeit df.groupby('id')['sex'].apply(lambda x: np.argmax(np.bincount(x))).reset_index()
100 loops, best of 3: 2.48 ms per loop
In [197]: %timeit df.groupby('id')['sex'].apply(lambda x: x.value_counts().index[0]).reset_index()
100 loops, best of 3: 4.55 ms per loop
In [198]: %timeit df.set_index('id').groupby(level=0).sex.apply(lambda x: x.value_counts().idxmax()).reset_index()
100 loops, best of 3: 6.71 ms per loop
我想用这个。。。但我做得不对,所以放弃了。谢谢你给我指明了正确的方法。如果你正在进行基准测试,你能同时对我的选项2进行基准测试吗?谢谢。@JohnGalt-我认为分组计时有点问题-只有少量的分组使用。更好的是df有更多的分类。@jezrael——好的观点,我同意,如果可以的话,请这样做。然而,我敢打赌bincount在大多数合理的情况下都会很快。似乎只使用
mode()
方法会更简单(可能不会更快):df.groupby(by=['id'])。apply(lambda x:x.mode())。reset_index(drop=True)
谢谢!“这真的很有帮助。”伦顿干杯。