【问题标题】:Python Pivot Table margins=True not summing wellPython Pivot Table margins=True 不能很好地求和
【发布时间】:2018-07-30 21:40:29
【问题描述】:

我有以下代码:

import pandas as pd
df=pd.read_csv("https://www.dropbox.com/s/90y07129zn351z9/test_data.csv?dl=1", encoding="latin-1")
pvt_received=df.pivot_table(index=['site'], values = ['received','sent'], aggfunc = {  'received' : 'count' ,'sent': 'count'}, fill_value=0, margins=True) 
pvt_received['to_send']=pvt_received['received']-pvt_received['sent']
column_order = ['received', 'sent','to_send']
pvt_received_ordered = pvt_received.reindex_axis(column_order, axis=1)
pvt_received_ordered.to_csv("test_pivot.csv")
table_to_send = pd.read_csv('test_pivot.csv', encoding='latin-1')
table_to_send.rename(columns={'site':'Site','received':'Date Received','sent':'Date Sent','to_send':'Date To Send'}, inplace=True)
table_to_send.set_index('Site', inplace=True)
table_to_send

生成此表:

      Date Received       Date Sent       Date To Send
Site            
2         32.0             27.0           5.0
3         20.0             17.0           3.0
4         33.0             31.0           2.0
5         40.0             31.0           9.0
All       106.0            106.0          0.0

但是这个参数 margins=True 没有给出每列总数的正确结果。例如,接收日期应该是 125 而不是 106,发送日期应该是 106(这是正确的),发送日期应该是 19 而不是 0.0(零)。问题:我应该改变什么以获得正确的数字?此外,缺少应该对每一行求和的所有内容。提前非常感谢。

【问题讨论】:

    标签: python pandas pivot-table


    【解决方案1】:

    从您的代码看来,您在构建数据透视表之后创建了Date To Send,因此它只是为您提供了以下结果:106.0 - 106.0。此外,它们的边距值为calculated,默认为dropna=True,分组后意味着任何带有NaN 或NaT 的行都将被删除。设置dropna=False 应该可以解决这个问题。

    在创建数据透视表和 to_send 列之前,我重构了您的代码以将 received 和 sent 列转换为 date_time 格式。

    df2 = pd.read_csv(
             "https://www.dropbox.com/s/90y07129zn351z9/test_data.csv?dl=1"
             ,encoding="latin-1")
    df2['received'] = pd.to_datetime(df2['received'])
    df2['sent'] = pd.to_datetime(df2['sent'])
    

    然后创建最初打算的数据透视表。

    pvt_received = df2.pivot_table(index=['site'], values=['received','sent'],\
        aggfunc='count', margins=True, dropna=False)
    
    pvt_received['to_send'] = pvt_received['received'] - pvt_received['sent']
    pvt_received.rename(columns={'site':'Site'
                                 ,'received':'Date Received'
                                 ,'sent':'Date Sent'
                                 ,'to_send':'Date To Send'}
                                 ,inplace=True)
    pvt_received
    
            Date Received   Date Sent   Date To Send
    Site            
    2       32              27          5
    3       20              17          3
    4       33              31          2
    5       40              31          9
    All     125             106         25
    

    【讨论】:

    • to_send 的值是错误的,发送日期应该是 19 而不是 106。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-31
    • 2014-11-14
    • 2012-02-06
    • 2014-03-12
    • 2013-12-08
    • 1970-01-01
    相关资源
    最近更新 更多