我的pandas数据框看起来像这样:
Name Hobby
Andrew Football
Kevin Photo
Andrew Football
Kevin Games
Andrew Travel
Kevin Games
理想的结果将是安德鲁:足球;凯文:游戏。这可以是字典或数据库。我不能只为一个名字排序,然后做爱好的idxmax,因为我的名字列可以用更多或更少的名字更新。我试过了:
sorted = sorted.drop_duplicates()
sorted1 = {k: g["Hobby"].tolist() for k,g in sorted.groupby("Names")}
但这会带来所有的爱好,而不仅仅是最经常的爱好。
答案 0 :(得分:2)
这是一个解决方案,它将返回由Name编制的系列以及与之关联的最常见的Hobby:
df.groupby('Name')['Hobby'].agg(lambda x: pd.value_counts(x).index[0])
Name
Andrew Football
Kevin Games
Name: Hobby, dtype: object
答案 1 :(得分:1)
您可以使用groupby
和size
加倍nlargest
的更快解决方案:
df3 = df.groupby(['Names', 'Hobby'])
.size()
.groupby(level=0)
.nlargest(1)
.reset_index(level=0, drop=True)
.reset_index(name='Count')
另一个解决方案是使用Counter
:
from collections import Counter
df1 = df.groupby('Names')['Hobby'].apply(lambda x: Counter(x).most_common(1)[0][0])
<强>计时强>:
In [52]: %timeit df.groupby(['Names', 'Hobby']).size().groupby(level=0).nlargest(1).reset_index(level=0, drop=True).reset_index(name='Count')
1 loop, best of 3: 191 ms per loop
In [53]: %timeit df.groupby('Names')['Hobby'].apply(lambda x: Counter(x).most_common(1)[0][0])
1 loop, best of 3: 242 ms per loop
In [54]: %timeit df.groupby('Names')['Hobby'].agg(lambda x: pd.value_counts(x).index[0])
1 loop, best of 3: 345 ms per loop
测试代码:
#[1000000 rows x 2 columns]
np.random.seed(123)
N = 1000000
L1 = ['Andrew', 'Kevin','Joe','John', 'Bob', 'Peter']
L2 = ['Football','Photo','Games','Travel']
df = pd.DataFrame({'Names':np.random.choice(L1, N),
'Hobby': np.random.choice(L1, N)})
print (df)