【问题标题】:Pandas New Dataframe Displaying Top and Bottom N Values Per GroupPandas 新数据框显示每组的顶部和底部 N 值
【发布时间】:2020-01-15 20:19:30
【问题描述】:

我有一个包含三列的 DataFrame:单位、影响者和价值。有几种不同类型的影响者,这些值代表单位的数量。 我想创建一个新表,显示每个影响者的最频繁和最不频繁的 n 个单位及其各自的值。

我的 df 看起来像这样:

Unit    Influencer    Value
A       foo           321
B       foo           200
C       foo           20
D       foo           12
E       foo           3
A       bar           999
B       bar           209
C       bar           89
D       bar           34
E       bar           15
F       bar           2

我的输出应该是这样的(假设我们想要顶部和底部 2 个单位):

Unit    Influencer    Value
    A       foo           321
    B       foo           200
    D       foo           12
    E       foo           3
    A       bar           999
    B       bar           209
    E       bar           15
    F       bar           2

我尝试了类似于找到here 的解决方案,但我收到错误“索引包含重复条目,无法重塑”,我认为这是因为“影响者”是我的 df 的索引。如果我的 df 是多索引,则创建新的 df,但它不正确。

def get_top3(counts, col1, col2):

    top3 = (counts.groupby(col1))[col2].apply(lambda x: x.nlargest(3)).reset_index(level=1, drop=True).to_frame('VAL')

    top3 = counts.set_index(np.arange(len(counts)) % 3, append=True)['value'].unstack().add_prefix('VAL')

    return top3

但是,这会创建一个如下所示的 Dataframe:

VAL1  VAL2  VAL3
321   NaN   NaN
NaN   200   NaN
NaN   NaN   20
12    NaN   NaN
NaN   3     NaN
...

任何建议将不胜感激!我也愿意就如何格式化我的输出 df 提供反馈。谢谢!

【问题讨论】:

  • 输出中缺少“A”,有什么具体原因吗?
  • 抱歉,我不得不移动我的一些值并忘记更改输出以反映这一点。我已经编辑了这个问题来解决这个问题。谢谢!

标签: python pandas dataframe


【解决方案1】:

你可以试试:

nlargest = df.groupby('Influencer')['Value'].nlargest(2).reset_index()['level_1'].values
nsmallest = df.groupby('Influencer')['Value'].nsmallest(2).reset_index()['level_1'].values

result = pd.concat([df.iloc[nlargest], df.iloc[nsmallest]]).sort_index()
print(result)

输出

   Unit Influencer  Value
0     A        foo    321
1     B        foo    200
3     D        foo     12
4     E        foo      3
5     A        bar    999
6     B        bar    209
9     E        bar     15
10    F        bar      2

【讨论】:

  • 非常感谢!这完美地工作。不过我很好奇,为什么我们需要 .reset_index() 在这种情况下?
  • 我这样做是为了访问级别 1 中的索引
【解决方案2】:

使用

#df=df.sort_values('Value')
g=df.groupby('Influencer')
pd.concat([g.head(2),g.tail(2)]).sort_index()
Out[693]: 
   Unit Influencer  Value
0     A        foo    321
1     B        foo    200
3     D        foo     12
4     E        foo      3
5     A        bar    999
6     B        bar    209
9     E        bar     15
10    F        bar      2

【讨论】:

    【解决方案3】:

    尝试创建如下函数:

    def selc_df(df, x=2):
        return df.head(x).append(df.tail(x))
    
    selc_df(df,2)
    

    示例:

    >>> df
       A    B
    0  1  345
    1  2  366
    2  3  299
    3  3  455
    4  4  879
    5  5  321
    6  5  957
    7  6  543
    

    结果:

    >>> def selc_df(df, x=2):
    ...     return df.head(x).append(df.tail(x))
    ...
    
    >>> selc_df(df,2)
       A    B
    0  1  345
    1  2  366
    6  5  957
    7  6  543
    

    【讨论】:

    • 这里的主要问题是我需要每个影响者的头部和尾部,而不是整个数据帧的头部和尾部。
    猜你喜欢
    • 2021-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-27
    • 2021-07-24
    • 2018-05-04
    相关资源
    最近更新 更多