【问题标题】:Iterative column max stats from dataframe pivot table and indexing来自数据框数据透视表和索引的迭代列最大统计信息
【发布时间】:2021-06-13 22:19:54
【问题描述】:

希望有人能帮我解决这个问题。

让我们考虑以下数据示例:

dfexample = pd.DataFrame(np.array([['apple','red','a',100],
                              ['apple','red','b',100],
                              ['apple','red','c',80],
                              ['apple','red','d',70],
                              ['apple','red','e',60],
                              ['apple','red','f',50],
                              ['apple','yellow','a',99],
                              ['apple','yellow','b',98],
                              ['apple','yellow','c',97],
                              ['apple','yellow','d',96],
                              ['apple','yellow','e',95],
                              ['apple','yellow','f',94],
                              ['apple','green','a',10],
                              ['apple','green','b',9],
                              ['apple','green','c',8],
                              ['apple','green','d',7],
                              ['apple','green','e',6],
                              ['apple','green','f',5]
                              ]),
                              columns=['fruit','colour','cat','score'])
                 
dfexample = dfexample.astype({"score": float})

我可以旋转数据以将 cat 转换为唯一列:

pivotexample = dfexample.pivot_table(index = ['fruit','colour'],
                         columns = ['cat'],
                         values = ['score'],
                         fill_value = 0).swaplevel(axis=1).sort_index(1)

print(pivotexample) 

输出:

cat              a     b     c     d     e     f
             score score score score score score
fruit colour                                    
apple green     10     9     8     7     6     5
      red      100   100    80    70    60    50
      yellow    99    98    97    96    95    94

是否可以迭代地计算每个 cat 列的最大值(在 cat 列 a -> f 上循环),以便返回带有 fruit_colour 索引的最大值,而不是循环中较早选择的索引。

从上面的例子我想返回:

猫,(最大)分数,fruit_colour

a, 100, apple_red(最大值)

b, 98, apple_yellow(最大值为 98,因为 100(apple_red) 被选为之前的最高索引)

c, 8, apple_green(8 最大值,因为 97(apple_yellow) 和 80(apple_red) 之前的最高索引)

手动 Excel 视图:

Excel view

非常感谢您的关注。

问候

############################################## ######################

编辑后提供的答案:

def calc_mystats(dx, picked_colors_):
    dx = dx.sort_values(by=['score'], ascending=False)
    for index, row in dx.iterrows():
        if row['colour'] not in picked_colors_:
            picked_colors_.append(row['colour'])
            return pd.Series([row['cat'], row['score'], row['fruit'] + "_" + row['colour']], index=['cat','(max)score', 'fruit_color'])    

picked_colors = ['none']
print(dfexample.groupby('cat').apply(calc_mystats, picked_colors))

print(picked_colors)

输出:

     cat  (max)score   fruit_color
cat                               
a      a        99.0  apple_yellow
b      b         9.0   apple_green
c    NaN         NaN           NaN
d    NaN         NaN           NaN
e    NaN         NaN           NaN
f    NaN         NaN           NaN
['none', 'red', 'yellow', 'green']

【问题讨论】:

    标签: python pandas numpy loops pivot-table


    【解决方案1】:

    我会改用 Panda 的 groupy ([docs][1]) 函数在数据框的列上迭代生成统计信息。首先,我将按我感兴趣的列(在您的情况下为cat)分组,然后应用行函数来计算组中行的一些统计信息。以下是我的做法。

    这是为每个 cat 计算 max_score 的函数,与您在问题中描述的相同:

    def calc_mystats(dx, picked_colors_):
    dx = dx.sort_values(by=['score'], ascending=False)
    for index, row in dx.iterrows():
        if row['colour'] not in picked_colors_:
            picked_colors_.append(row['colour'])
            return pd.Series([row['cat'], row['score'], row['fruit'] + "_" + row['colour']], index=['cat','(max)score', 'fruit_color'])
    

    然后我将执行实际的 groupy pandas 操作并应用上述功能。

    picked_colors = []
    print(dfexample.groupby('cat').apply(calc_mystats, picked_colors))
    

    请注意,picked_colors 列表被传递给我们的函数calc_mystats 以维护所选颜色的记录,以免两次选择相同的颜色。

    这是您的最终输出(这是一个数据框)

         cat  (max)score   fruit_color
    cat                               
    a      a       100.0     apple_red
    b      b        98.0  apple_yellow
    c      c         8.0   apple_green
    d    NaN         NaN           NaN
    e    NaN         NaN           NaN
    f    NaN         NaN           NaN
    

    您可能需要处理groupbyapply 操作之后的结果。例如,在您的情况下,您可以使用 dropna()

    参考文献:[1]:https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.groupby.html

    【讨论】:

    • 感谢@raghu.tjm 的精彩回答。
    • 我已将您的解决方案添加到问题中。只是一个问题,当我执行代码时,它似乎删除了第一个索引,即在这种情况下为 apple_red。我尝试了另一个数据表,似乎也发生了同样的情况。我检查了pick_color 的内容,它们似乎都存在。问候
    • 我刚刚检查了代码并再次运行。它不应该放弃index。您可以尝试再次运行代码吗?我清理了一些东西
    • 删除了df_out。那不应该是你的最终输出。你的输出应该是print(dfexample.groupby('cat').apply(calc_mystats, picked_colors))
    • 谢谢@raghu.tjm
    猜你喜欢
    • 2020-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-29
    • 2022-10-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多