在分组数据上添加计算列

时间:2017-09-18 16:35:50

标签: python pandas

我正在使用Pandas并创建了2个数据透视表,然后使用以下代码将它们交错为1个数据帧:

df_sales = pd.read_sql_query(sales_query, cnxn, params=[report_start, end_mtd, whse])                                
print('executing sales sql for warehouse : ' + whse)                                                                 
df_sales['PERIOD'] = (((df_sales['INV_MONTH'].astype(str) + '/' + df_sales['INV_YEAR'].astype(str))))                
df_sales = pd.pivot_table(df_sales, index=['REP', 'CUST_NO'], columns=['PERIOD'], values=['SALES'], fill_value=0)    

df_profit = pd.read_sql_query(profit_query, cnxn, params=[report_start, end_mtd, whse])                              
print('executing profit sql for warehouse : ' + whse)                                                                
df_profit['PERIOD'] = (((df_profit['INV_MONTH'].astype(str) + '/' + df_profit['INV_YEAR'].astype(str))))             
df_profit = pd.pivot_table(df_profit, index=['REP', 'CUST_NO'], columns=['PERIOD'], values=['PROFIT'], fill_value=0) 

df = pd.concat([df_sales, df_profit], axis=1)[list(interleave([df_sales, df_profit]))]    

我的输出如下:

SALES     PROFIT     SALES    PROFIT       
01/2017    01/2017   02/2017   02/2017
$96.01     $23.18  $7,347.66   $1,267.72    
$600.00    $146.35   $600.00   $147.15   

我想在此表中添加一个计算的df['MARGIN']列,以提供输出:

SALES     PROFIT     MARGIN    SALES       PROFIT      MARGIN
01/2017    01/2017   02/2017   02/2017     02/2017     02/2017
$96.01     $23.18    24.14%    $7,347.66   $1,267.72    17.25%
$600.00    $146.35   24.39%     $600.00    $147.15      24.53%

我尝试使用df['MARGIN'] = df['PROFIT'] / df['SALES'],但收到错误:

ValueError: Wrong number of items passed 12, placement implies 1

假设这是错误,因为我在报告中包含了12个句点。

2 个答案:

答案 0 :(得分:1)

只要您的列索引已排序,您就可以执行您想要的操作。

假设:

df = pd.concat([df_sales, df_profit], axis=1)

为您提供具有两级分层索引的数据框,您可以这样做:

df = pd.concat([df_sales, df_profit], axis=1)
df["MARGIN"] = df["PROFIT"] / df["SALES"]

如果此操作失败,则因为未对列索引进行排序。您只需执行以下操作即可解决此问题:

df = pd.concat([df_sales, df_profit], axis=1)
df.sort_index(axis=1, inplace=True)
df["MARGIN"] = df["PROFIT"] / df["SALES"]

然后你就像以前一样交错列。

更新

最终交错的丑陋解决方案:

n = len(df.columns) // 3
# Using sum for lists is highly discouraged! But convenient in this case :)
cols = sum(([j * n + i for j in range(3)] for i in range(n)), [])
df = df.iloc[:, cols]

答案 1 :(得分:0)

您是否希望Pandas以某种方式知道当您说保证金等于利润除以销售额时,您的意思是特定日期的保证金等于该日期的利润除以该日期的销售额?熊猫不是心灵读者。假设您正在使用多索引,您可以这样做:

for reporting_date in df.columns.get_level_values(1):
    df['MARGIN',reporting_date'] = df['PROFIT',reporting_date']/df['SALES',reporting_date']

然而,这可能仍会返回错误;鉴于你有美元符号和逗号,大概是金额存储为字符串。你应该把它们存储为int或float,如果你真的想看到它们显示为美元,那就写一个display_as_dollars函数。

编辑:您也可以尝试df ['MARGIN'] = df ['PROFIT']。div(df ['SALES'])