【问题标题】:Pandas pivot_table: filter on aggregate functionPandas pivot_table:过滤聚合函数
【发布时间】:2021-08-24 00:28:53
【问题描述】:

我正在尝试将标准传递给 pandas pivot_table 的聚合函数,但我无法弄清楚如何将标准传递给 aggfunc。我有一个转换为 pandas df 的数据表。

输入表数据:

col1 col2 col3 col4 col5 col6 col7
1 test1 t1 Dummy1 result1 10 102.2
2 test1 t1 Dummy2 result2 20 101.2
3 test1 t1 Dummy3 result3 30 102.3
4 test1 t1 Dummy4 result4 40 101.4
5 test2 t1 Dummy1 result1 10 100
6 test2 t1 Dummy2 result2 20 103
7 test2 t1 Dummy3 result3 30 104
8 test2 t1 Dummy4 result4 40 105
9 test3 t1 Dummy1 result1 10 102
10 test3 t1 Dummy2 result2 20 87
11 test3 t1 Dummy3 result3 30 107
12 test3 t1 Dummy5 result4 50 110.2
13 test4 t1 Dummy2 result2 20 120
14 test5 t1 Dummy6 result1 100 88
15 test1 t1 Dummy1 result2 10 106.2
16 test1 t1 Dummy1 result6 10 101.1

我想获取 col7 数据的最大值,但仅当最大值大于 100 时。如果任何 col7 数据大于用户定义的标准,则需要填充所有其他列数据,无论是否数据是否符合标准。

尝试了以下方法:

columns = ['col1', 'col2', 'col3', 'col4', 'col5', 'col6', 'col7']

df = pd.DataFrame({
    'col1': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
    'col2': ['test1', 'test1', 'test1', 'test1', 'test2', 'test2', 'test2',
             'test2', 'test3', 'test3', 'test3', 'test3', 'test4', 'test5',
             'test1', 'test1'],
    'col3': ['t1', 't1', 't1', 't1', 't1', 't1', 't1', 't1', 't1', 't1', 't1',
             't1', 't1', 't1', 't1', 't1'],
    'col4': ['Dummy1', 'Dummy2', 'Dummy3', 'Dummy4', 'Dummy1', 'Dummy2',
             'Dummy3', 'Dummy4', 'Dummy1', 'Dummy2', 'Dummy3', 'Dummy5',
             'Dummy2', 'Dummy6', 'Dummy1', 'Dummy1'],
    'col5': ['result1', 'result2', 'result3', 'result4', 'result1', 'result2',
             'result3', 'result4', 'result1', 'result2', 'result3', 'result4',
             'result2', 'result1', 'result2', 'result6'],
    'col6': [10, 20, 30, 40, 10, 20, 30, 40, 10, 20, 30, 50, 20, 100, 10, 10],
    'col7': [100.2, 101.2, 102.3, 101.4, 100.0, 103.0, 104.0, 105.0, 102.0,
             87.0, 107.0, 110.2, 120.0, 88.0, 106.2, 101.1]
})

res=df.pivot_table(values = 'col7', index = ['col4', 'col5', 'col6'], columns = ['col2'], fill_value = '', aggfunc = 'max' >= 100)
TypeError: '>=' not supported between instances of 'str' and 'int'

输出应如下所示:

不带 col5 的最大旋转输出:

col4 col6 test1 test2 test3 test4 test5
Dummy1 10 106.2 100 102 N/A N/A
Dummy2 20 101.2 103 87 120 N/A
Dummy3 30 102.3 104 107 N/A N/A
Dummy4 40 101.4 105 N/A N/A N/A
Dummy5 50 N/A N/A 110.2 N/A N/A

最大旋转输出,包括 col5:

col4 col5 col6 test1 test2 test3 test4 test5
Dummy1 result2 10 106.2 N/A N/A N/A N/A
Dummy1 result1 10 102.2 100 102 N/A N/A
Dummy2 result2 20 101.2 103 87 120 N/A
Dummy3 result3 30 102.3 104 107 N/A N/A
Dummy4 result4 40 101.4 105 N/A N/A N/A
Dummy5 result4 50 N/A N/A 110.2 N/A N/A

非常感谢任何指导。

谢谢

【问题讨论】:

  • @Henry 我更新了输出表。我展示了包含 col4、col5 和 col6 作为索引的最终输出。我还展示了一个没有 col5 的输出,它显示了每列的最大值,但是当你将 col5 添加到组合中时,表格会发生变化,这就是我试图描绘的,这就是我想要实现的最终输出。谢谢
  • @Henry 感谢您的更新。我需要带有 col5 的表。我只是在没有 col5 的情况下展示了我如何创建包含 col5 的表的参考。看起来我可能通过在组合中添加没有 col5 的表来引起更多的混乱。我正在寻找的最终输出表是操作中“最大旋转输出,包括 col5:”下面的表。
  • 再次,我不明白为什么result6 不在结果集中。它高于 100 阈值。这是我的输出和你的输出之间的唯一区别......你在找什么?
  • @Henry result6 不在数据集中,因为它不是最高的。对于 Dummy1,我们有三个 col5 值(result1、result2、result6),并且在所有三个 col5 值中,我们试图只获得最高的值,即 106.2。假设我们只有一列是“test1”,那么输出应该是 Dummy1-result2-10-106.2
  • 好的。我想你是说每个组应该有一个条目,然后你想用对应于最大值的值重新填充 col5。在那种情况下,我不明白为什么Dummy1 在输出表中有result2result1

标签: python pandas dataframe pandas-groupby pivot-table


【解决方案1】:

您无法通过>= (aggfunc = 'max' >= 100) 将“最大”一词与 100 进行比较:

我建议不要将填充值设置为字符串,屏蔽 DataFrame,以摆脱不需要的行,然后通过fillna替换为空字符串:

columns = ['col1', 'col2', 'col3', 'col4', 'col5', 'col6', 'col7']
res = df.pivot_table(values='col7', index=['col4', 'col5', 'col6'],
                     columns=['col2'], aggfunc='max')
col2                 test1  test2  test3  test4  test5
col4   col5    col6                                   
Dummy1 result1 10    102.2  100.0  102.0    NaN    NaN
       result2 10    106.2    NaN    NaN    NaN    NaN
       result6 10    101.1    NaN    NaN    NaN    NaN
Dummy2 result2 20    101.2  103.0   87.0  120.0    NaN
Dummy3 result3 30    102.3  104.0  107.0    NaN    NaN
Dummy4 result4 40    101.4  105.0    NaN    NaN    NaN
Dummy5 result4 50      NaN    NaN  110.2    NaN    NaN
Dummy6 result1 100     NaN    NaN    NaN    NaN   88.0

屏蔽any res >= 100fillna 的任何值:

res = res[(res >= 100).any(1)].fillna('')
col2                 test1  test2  test3  test4 test5
col4   col5    col6                                  
Dummy1 result1 10    102.2  100.0  102.0             
       result2 10    106.2                           
       result6 10    101.1                           
Dummy2 result2 20    101.2  103.0   87.0  120.0      
Dummy3 result3 30    102.3  104.0  107.0             
Dummy4 result4 40    101.4  105.0                    
Dummy5 result4 50                  110.2                       

可选reset_index 清除MultiIndex 和rename_axis 清除轴名称:

res[(res >= 100).any(1)].fillna('').reset_index().rename_axis(None, axis=1)
     col4     col5  col6  test1  test2  test3  test4 test5
0  Dummy1  result1    10  102.2  100.0  102.0             
1  Dummy1  result2    10  106.2                           
2  Dummy1  result6    10  101.1                           
3  Dummy2  result2    20  101.2  103.0   87.0  120.0      
4  Dummy3  result3    30  102.3  104.0  107.0             
5  Dummy4  result4    40  101.4  105.0                    
6  Dummy5  result4    50                110.2             

完整的工作示例:

import pandas as pd

df = pd.DataFrame({
    'col1': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
    'col2': ['test1', 'test1', 'test1', 'test1', 'test2', 'test2', 'test2',
             'test2', 'test3', 'test3', 'test3', 'test3', 'test4', 'test5',
             'test1', 'test1'],
    'col3': ['t1', 't1', 't1', 't1', 't1', 't1', 't1', 't1', 't1', 't1', 't1',
             't1', 't1', 't1', 't1', 't1'],
    'col4': ['Dummy1', 'Dummy2', 'Dummy3', 'Dummy4', 'Dummy1', 'Dummy2',
             'Dummy3', 'Dummy4', 'Dummy1', 'Dummy2', 'Dummy3', 'Dummy5',
             'Dummy2', 'Dummy6', 'Dummy1', 'Dummy1'],
    'col5': ['result1', 'result2', 'result3', 'result4', 'result1', 'result2',
             'result3', 'result4', 'result1', 'result2', 'result3', 'result4',
             'result2', 'result1', 'result2', 'result6'],
    'col6': [10, 20, 30, 40, 10, 20, 30, 40, 10, 20, 30, 50, 20, 100, 10, 10],
    'col7': [102.2, 101.2, 102.3, 101.4, 100.0, 103.0, 104.0, 105.0, 102.0,
             87.0, 107.0, 110.2, 120.0, 88.0, 106.2, 101.1]
})

columns = ['col1', 'col2', 'col3', 'col4', 'col5', 'col6', 'col7']
res = df.pivot_table(values='col7', index=['col4', 'col5', 'col6'],
                     columns=['col2'], aggfunc='max')
res = (
    res[(res >= 100).any(1)].fillna('').reset_index().rename_axis(None, axis=1)
)
print(res)

要获取不带 col5 的值,请将其从 indexpivot_table 中删除:

columns = ['col1', 'col2', 'col3', 'col4', 'col5', 'col6', 'col7']
res = df.pivot_table(values='col7', index=['col4', 'col6'],
                     columns=['col2'], aggfunc='max')
res = (
    res[(res >= 100).any(1)].fillna('').reset_index().rename_axis(None, axis=1)
)
     col4  col6  test1  test2  test3  test4 test5
0  Dummy1    10  106.2  100.0  102.0             
1  Dummy2    20  101.2  103.0   87.0  120.0      
2  Dummy3    30  102.3  104.0  107.0             
3  Dummy4    40  101.4  105.0                    
4  Dummy5    50                110.2             

【讨论】:

  • 我不确定我是否清楚我的描述,因为我得到的解决方案与我在完整数据集上运行时所需的解决方案不同。即使我在多个列上建立索引,我的意图是使用 col4 作为索引以及 col5 和 col6 的相应数据来获取最大值。使用建议的 sol,col4“Dummy1”重复三次,因为我们为 Dummy1 提供了三个唯一的 col5 标签,但目的是从 col5 中仅获取 1 个数据点,其中 col5 是对应 col4“Dummy1”的最大值。我已经更新了帖子中的输出。如果您愿意,我可以单独发布一个问题。
  • 由于没有其他人回答原始问题,如果您能看一下,我将不胜感激。谢谢
【解决方案2】:

或者你可以试试:

res = df.assign(col7 = df.col7.where(df.col7 > 100)).pivot_table(values='col7', index=['col4', 'col5', 'col6'],
                     columns=['col2'], aggfunc='max', fill_value= '')

【讨论】:

    猜你喜欢
    • 2022-11-15
    • 1970-01-01
    • 2021-03-03
    • 2023-02-16
    • 2017-07-03
    • 1970-01-01
    • 2021-03-14
    • 2018-10-31
    • 2016-07-06
    相关资源
    最近更新 更多