pandas数据帧,并在n个最常用的值上使用idmax()

时间:2015-08-03 17:35:29

标签: python pandas

我有一个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),只要选择三种可能性中的两种,顺序并不重要。如果有人一天只去了商店(比如蒂姆),我希望第二个地点为空。这是我想要的输出:

    names  'Most frequent'   '2nd most freq'
    'Martha'    'Thu'            'Mon'
    'Johnny'    'Wed'            'Mon'
    'Chloe'     'Tue'            'Thu'
    'Tim'       'Mon'             NaN

我已经看到类似的问题,询问有关扩展argmax(),但不是idmax()。

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

    for customer in dataframe:
        for i  = 0,1:
            if all elements zero:
                newdataframe[customer, i] = NaN
            else:
                newdataframe[customer, i] = dataframe.idxmax()[customer]
                dataframe[dataframe.idxmax()[customer], customer] = 0
         return newdataframe

我想有一个比我更有经验的人可能会更有效率地做到这一点。你怎么看?有更有效的方法吗?

2 个答案:

答案 0 :(得分:1)

由于您还想要第二个最常见的日子,您可以定义一个自定义函数来对每列进行排序。

# 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

答案 1 :(得分:1)

df.stack(-1).groupby(level=-1).transform(lambda x: x.argsort(0)).reset_index().pivot('level_1',0).sort_index(axis = 1, ascending = False)