基于最常见字符串的Dataframe列排序

时间:2016-11-24 13:46:34

标签: python-2.7 sorting pandas dictionary dataframe

我的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")}

但这会带来所有的爱好,而不仅仅是最经常的爱好。

2 个答案:

答案 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)

您可以使用groupbysize加倍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)