获取 Pandas Dataframe 中列名的排名

我将客户 ID 与他们最常购买的表演类型进行了对比:


Genre            Jazz     Dance     Music  Theatre

Customer                                        

100000000001           0      3         1        2

100000000002           0      1         6        2

100000000003           0      3        13        4

100000000004           0      5         4        1

100000000005           1     10        16       14

我想要的结果是根据排名附加列名:


Genre            Jazz     Dance     Music  Theatre          Rank1          Rank2          Rank3          Rank4

Customer                                         

100000000001           0      3         1        2          Dance        Theatre          Music           Jazz

100000000002           0      1         6        2          Music        Theatre          Dance           Jazz

100000000003           0      3        13        4          Music        Theatre          Dance           Jazz

100000000004           0      5         4        1          Dance          Music        Theatre           Jazz

100000000005           1     10        16       14          Music        Theatre          Dance           Jazz

我已经查找了一些线程,但我能找到的最接近的是idxmax. 然而,那只会给我Rank1。


谁能帮我得到我需要的结果?


慕的地6264312
浏览 186回答 5
5回答

慕标琳琳

使用:i = np.argsort(df.to_numpy() * -1, axis=1)r = pd.DataFrame(df.columns[i], index=df.index, columns=range(1, i.shape[1] + 1)) df = df.join(r.add_prefix('Rank'))细节:使用np.argsortalong获取将按降序对流派进行排序的axis=1索引。iprint(i) array([[1, 3, 2, 0],        [2, 3, 1, 0],        [2, 3, 1, 0],        [1, 2, 3, 0],        [2, 3, 1, 0]])从沿着索引(即)获取的r数据框的列创建一个新的数据框,然后使用连接数据框:dfidf.columns[i]DataFrame.joinrdfprint(df)              Jazz  Dance  Music  Theatre  Rank1    Rank2    Rank3 Rank4Customer                                                                100000000001     0      3      1        2  Dance  Theatre    Music  Jazz100000000002     0      1      6        2  Music  Theatre    Dance  Jazz100000000003     0      3     13        4  Music  Theatre    Dance  Jazz100000000004     0      5      4        1  Dance    Music  Theatre  Jazz100000000005     1     10     16       14  Music  Theatre    Dance  Jazz

qq_遁去的一_1

尝试这个:dfp = (df.rank(ascending=False, axis=1).stack()         .astype(int).rename('rank').reset_index(level=1))df.assign(**dfp.set_index('rank', append=True)['Genre'].unstack().add_prefix('Rank'))输出:Genre         Jazz  Dance  Music  Theatre  Rank1    Rank2    Rank3 Rank4Customer                                                                100000000001     0      3      1        2  Dance  Theatre    Music  Jazz100000000002     0      1      6        2  Music  Theatre    Dance  Jazz100000000003     0      3     13        4  Music  Theatre    Dance  Jazz100000000004     0      5      4        1  Dance    Music  Theatre  Jazz100000000005     1     10     16       14  Music  Theatre    Dance  Jazz使用rank并重塑数据框,然后使用assign.

动漫人物

让我们试试stack,cumcount和sort_values:s = df.stack().sort_values(ascending=False).groupby(level=0).cumcount() + 1s1 = (s.reset_index(1)    .set_index(0, append=True)    .unstack(1)    .add_prefix("Rank")        )s1.columns = s1.columns.get_level_values(1)然后加入您的客户类型索引。df.join(s1)                 Jazz  Dance  Music  Theatre  Rank1    Rank2    Rank3 Rank4Customer_Genre                                                            100000000001       0      3      1        2  Dance  Theatre    Music  Jazz100000000002       0      1      6        2  Music  Theatre    Dance  Jazz100000000003       0      3     13        4  Music  Theatre    Dance  Jazz100000000004       0      5      4        1  Dance    Music  Theatre  Jazz100000000005       1     10     16       14  Music  Theatre    Dance  Jazz

HUH函数

上述解决方案有效,但我们现在收到以下弃用警告。r = pd.DataFrame(df.columns[i], index=df.index, columns=range(1, i.shape[1] + 1))FutureWarning:对多维索引(例如obj[:, None])的支持已弃用,并将在未来版本中删除。在索引之前转换为 numpy 数组。修订:r = pd.DataFrame(np.array(df.columns)[i], index=df.index, columns=range(1, i.shape[1] + 1))

慕容708150

这是一个改进以前答案的函数,考虑到以下几点:它通过在索引它们之前将 df.columns 转换为 numpy 数组来解决 Wally 提到的弃用警告。它还允许包含 NaN 值并避免将这些列用于排名列(也将它们的值保留为 NaN)。检查示例。它还添加了相应的排名值以轻松映射它们。如果您想按升序或降序对它们进行排名,则有一个附加参数。添加一个附加列,指定哪些列具有 NaN 值并且未包含在排名列中。这些值被添加到列表中。# Example DataFrameimport numpy as npimport pandas as pddic = {'A': [0, np.nan, 2, np.nan],      'B': [3, 0, 1, 5],      'C': [1, 2, 0, np.nan]}df = pd.DataFrame(dic)print(df)     A  B    C0  0.0  3  1.01  NaN  0  2.02  2.0  1  0.03  NaN  5  NaN# Functiondef fun_rank_columns(df, ascending=False):    factor = 1 if ascending else -1    # Rank columns showing ranking of column names    np_sort = np.argsort(df.to_numpy() * factor, axis=1)    df_rank = pd.DataFrame(np.array(df.columns)[np_sort], index=df.index, columns=range(1, np_sort.shape[1] + 1))        # Corresponding values for each rank column    np_sort_value = np.sort(df.to_numpy() * factor, axis=1)    df_rank_value = pd.DataFrame(np_sort_value, index=df.index, columns=range(1, np_sort_value.shape[1] + 1)) * factor        # Columns with nan values to be replaced    num_col_rank = df_rank.shape[1]    df_rank['nan_value'] = df.apply(lambda row: [i for i in df.columns if np.isnan(row[i])], axis=1)    for col in range(1, num_col_rank + 1):        condition = df_rank.apply(lambda x: x[col] in x['nan_value'], axis=1)        df_rank.loc[condition, col] = np.nan        df_rank_value.loc[condition, col] = np.nan    # Join Results    df_rank = df_rank.add_prefix('rank_')    df_rank_value = df_rank_value.add_prefix('rank_value_')    df_res = df_rank.join(df_rank_value)    return df_res# Apply the functiondf_res = fun_rank_columns(df, ascending=True)print(df_res)  rank_1 rank_2 rank_3 rank_nan_value  rank_value_1  rank_value_2  rank_value_30      A      C      B             []           0.0           1.0           3.01      B      C    NaN            [A]           0.0           2.0           NaN2      C      B      A             []           0.0           1.0           2.03      B    NaN    NaN         [A, C]           5.0           NaN           NaN
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python