Python 使用dataframe,并对n个最频繁的值使用idmax()

Python 使用dataframe,并对n个最频繁的值使用idmax(),python,pandas,Python,Pandas,我有一个pandas数据框架,其中行有一周中的几天,列有一个名称。数据框内是整数,表示该人员在该工作日进入商店的次数。看起来是这样的: names 'Martha' 'Johnny' 'Chloe' 'Tim' 'Mon' 3 2 0 7 'Tue' 0 0 3 0 'Wed' 1 12 3 0

我有一个pandas数据框架,其中行有一周中的几天,列有一个名称。数据框内是整数,表示该人员在该工作日进入商店的次数。看起来是这样的:

    names   'Martha'  'Johnny'  'Chloe'  'Tim'
    'Mon'     3          2        0       7
    'Tue'     0          0        3       0
    'Wed'     1          12       3       0
    'Thu'     5          0        3       0
我想为每个客户对他们一周中倾向于购物的几天进行排名,并选择前两天。在重复的情况下(例如Chloe),顺序并不重要,只要选择三种可能性中的两种。如果有人只在某一天去了商店(例如Tim),我希望第二个位置为空。这是我想要的输出:

    names  'Most frequent'   '2nd most freq'
    'Martha'    'Thu'            'Mon'
    'Johnny'    'Wed'            'Mon'
    'Chloe'     'Tue'            'Thu'
    'Tim'       'Mon'             NaN
我见过关于扩展argmax()而不是idmax()的类似问题

我当前的计划(伪代码):


我想象一个比我更有经验的人可能会更有效率地完成这项工作。你怎么认为?有没有更有效的方法?

因为您还需要第二个最频繁的一天,所以您可以定义一个自定义函数来对每个列进行排序

# your data
# ===========================
df

     Martha  Johnny  Chloe  Tim
Mon       3       2      0    7
Tue       0       0      3    0
Wed       1      12      3    0
Thu       5       0      3    0

# processing
# ======================
def func(col):
    # sort index according column values
    idx_sorted, _ = zip(*sorted(zip(col.index.values, col.values), key=lambda x: x[1]))
    return pd.Series({'most_frequent': idx_sorted[-1], 'second_most_freq': idx_sorted[-2]})

df.apply(func).T

       most_frequent second_most_freq
Martha           Thu              Mon
Johnny           Wed              Mon
Chloe            Thu              Wed
Tim              Mon              Thu
编辑:
看起来您需要一个特殊的熊猫透视表。试试看,谢谢你的回答——它非常聪明:)有没有办法修改它,让蒂姆的第二个最频繁的次数等于楠?@cnrk我编辑了这篇文章。我能想到的最简单的方法是将它做成一个字典,然后使用
get
方法,如果不存在搜索键,该方法将返回
None
或一个自定义值
np.nan
。您确实需要对此进行一些解释
# your data
# ===========================
df

     Martha  Johnny  Chloe  Tim
Mon       3       2      0    7
Tue       0       0      3    0
Wed       1      12      3    0
Thu       5       0      3    0

# processing
# ======================
def func(col):
    # sort index according column values
    idx_sorted, _ = zip(*sorted(zip(col.index.values, col.values), key=lambda x: x[1]))
    return pd.Series({'most_frequent': idx_sorted[-1], 'second_most_freq': idx_sorted[-2]})

df.apply(func).T

       most_frequent second_most_freq
Martha           Thu              Mon
Johnny           Wed              Mon
Chloe            Thu              Wed
Tim              Mon              Thu
# processing
# ======================
import numpy as np

def func(col):
    # sort index according column values
    col = col[col > 0]
    idx_sorted, _ = zip(*sorted(zip(col.index.values, col.values), key=lambda x: x[1]))
    d = dict(zip(np.arange(len(idx_sorted)), idx_sorted[::-1]))
    return pd.Series({'most_frequent': d.get(0, np.nan), 'second_most_freq': d.get(1, np.nan)})

df.apply(func).T

       most_frequent second_most_freq
Martha           Thu              Mon
Johnny           Wed              Mon
Chloe            Thu              Wed
Tim              Mon              NaN
df.stack(-1).groupby(level=-1).transform(lambda x: x.argsort(0)).reset_index().pivot('level_1',0).sort_index(axis = 1, ascending = False)