我有一个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
我想有一个比我更有经验的人可能会更有效率地做到这一点。你怎么看?有更有效的方法吗?
答案 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)