【问题标题】:How to compute a ratio between two filtered variables in a 'tidy' Pandas data frame如何计算“整洁”熊猫数据框中两个过滤变量之间的比率
【发布时间】:2020-06-12 02:20:24
【问题描述】:

我有以下“整洁”(长)格式的 Pandas 数据框:

df = pd.DataFrame({'Manufacturer':['Ford', 'Mercedes', 'BMW', 'Ford', 'Mercedes', 'BMW', 'Ford', 'Mercedes', 'BMW', 'Ford', 'Mercedes', 'BMW', 'Ford', 'Mercedes', 'BMW', 'Ford', 'Mercedes', 'BMW'],
                          'Metric':['Orders', 'Orders', 'Orders', 'Orders', 'Orders', 'Orders', 'Sales', 'Sales', 'Sales', 'Sales', 'Sales', 'Sales', 'Warranty', 'Warranty', 'Warranty', 'Warranty', 'Warranty', 'Warranty'],
                          'Sector':['Germany', 'Germany', 'Germany', 'USA', 'USA', 'USA', 'Germany', 'Germany', 'Germany', 'USA', 'USA', 'USA', 'Germany', 'Germany', 'Germany', 'USA', 'USA', 'USA'],
                          'Value':[45000, 70000, 65000, 40000, 65000, 63000, 2700, 4400, 3400, 3000, 4700, 5700, 1500, 2000, 2500, 1300, 2000, 2450],
                       })

我正在尝试计算订单与销售额之间的比率,按制造商和部门细分。

我根据Pandas percentage of total with groupby 中提供的答案尝试了几种方法(例如 groupby、transform 等),但其中任何一种方法都不成功(可能是由于数据的结构有点不同,而且不需要过滤)。

最终目标是制作一个条形图,显示按部门和制造商细分的订单与销售比率,类似于以下内容:

问题:我将如何计算订单与销售额之间的比率(按制造商和部门细分)作为绘制结果的方法?

提前致谢!


/////////////////////////////////////// //// 更新/////////////////////////////////// ///

如果我们修改数据框以包含另一列,这会导致其中一个索引中出现重复数据,则会出现错误。

这是更新后的数据框,带有一个新的City 列:

test_df = pd.DataFrame({'Manufacturer':['Ford', 'Ford', 'Mercedes', 'BMW', 'Ford', 'Mercedes', 'BMW', 'Ford', 'Mercedes', 'BMW', 'Ford', 'Mercedes', 'BMW', 'Ford', 'Mercedes', 'BMW', 'Ford', 'Mercedes', 'BMW'],
                          'Metric':['Orders', 'Orders', 'Orders', 'Orders', 'Orders', 'Orders', 'Orders', 'Sales', 'Sales', 'Sales', 'Sales', 'Sales', 'Sales', 'Warranty', 'Warranty', 'Warranty', 'Warranty', 'Warranty', 'Warranty'],
                          'Sector':['Germany', 'Germany', 'Germany', 'Germany', 'USA', 'USA', 'USA', 'Germany', 'Germany', 'Germany', 'USA', 'USA', 'USA', 'Germany', 'Germany', 'Germany', 'USA', 'USA', 'USA'],
                          'Value':[45000, 70000, 90000, 65000, 40000, 65000, 63000, 2700, 4400, 3400, 3000, 4700, 5700, 1500, 2000, 2500, 1300, 2000, 2450],
                          'City': ['Frankfurt', 'Bremen', 'Berlin', 'Hamburg', 'New York', 'Chicago', 'Los Angeles', 'Dresden', 'Munich', 'Cologne', 'Miami', 'Atlanta', 'Phoenix', 'Nuremberg', 'Dusseldorf', 'Leipzig', 'Houston', 'San Diego', 'San Francisco']
                       })

运行以下:

s1=df.set_index(['Manufacturer','Sector']).query("Metric=='Orders'").Value
s2=df.set_index(['Manufacturer','Sector']).query("Metric=='Sales'").Value

s1.div(s2).unstack().plot(kind='bar')

导致以下错误:

`ValueError: Index contains duplicate entries, cannot reshape`

原因是因为这些重复:

Manufacturer   Metric   Sector    Value    City
Ford           Orders   Germany   45000    Frankfurt
Ford           Orders   Germany   70000    Bremen

我尝试使用来自Pandas unstack problems: ValueError: Index contains duplicate entries, cannot reshape 的以下内容来处理这个用例:

df.reset_index().pivot_table(values = 'Value', index = ['Manufacturer', 'Metric'], aggfunc='sum')

但是,我没有成功,仍然收到有关重复值的错误消息。

有人对如何解决这个问题有任何想法吗?

提前致谢!

【问题讨论】:

    标签: python pandas pandas-groupby


    【解决方案1】:

    我将代码创建为按制造商和生产国家/地区比较订单和销售额的图表。

    sales = df[df['Metric'] == 'Sales'].set_index(['Manufacturer','Sector']).groupby(level=[0,1])['Value'].sum().to_frame('Sales')
    
    orders = df[df['Metric'] == 'Orders'].set_index(['Manufacturer','Sector']).groupby(level=[0,1])['Value'].sum().to_frame('Orders')
    df2 = orders.merge(sales, on=['Manufacturer','Sector'])
    
    df2
                  Orders    Sales
    Manufacturer Sector     
    BMW      Germany    65000   3400
             USA        63000   5700
    Ford     Germany    115000  2700
             USA        40000   3000
    Mercedes Germany    90000   4400
             USA        65000   4700
    
    df2.plot(kind='bar')
    

    【讨论】:

      【解决方案2】:

      经过一些额外的测试,我找到了解决方案:

      test_df = pd.DataFrame({'Manufacturer':['Ford', 'Ford', 'Mercedes', 'BMW', 'Ford', 'Mercedes', 'BMW', 'Ford', 'Mercedes', 'BMW', 'Ford', 'Mercedes', 'BMW', 'Ford', 'Mercedes', 'BMW', 'Ford', 'Mercedes', 'BMW'],
                                'Metric':['Orders', 'Orders', 'Orders', 'Orders', 'Orders', 'Orders', 'Orders', 'Sales', 'Sales', 'Sales', 'Sales', 'Sales', 'Sales', 'Warranty', 'Warranty', 'Warranty', 'Warranty', 'Warranty', 'Warranty'],
                                'Sector':['Germany', 'Germany', 'Germany', 'Germany', 'USA', 'USA', 'USA', 'Germany', 'Germany', 'Germany', 'USA', 'USA', 'USA', 'Germany', 'Germany', 'Germany', 'USA', 'USA', 'USA'],
                                'Value':[45000, 70000, 90000, 65000, 40000, 65000, 63000, 2700, 4400, 3400, 3000, 4700, 5700, 1500, 2000, 2500, 1300, 2000, 2450],
                                'City': ['Frankfurt', 'Bremen', 'Berlin', 'Hamburg', 'New York', 'Chicago', 'Los Angeles', 'Dresden', 'Munich', 'Cologne', 'Miami', 'Atlanta', 'Phoenix', 'Nuremberg', 'Dusseldorf', 'Leipzig', 'Houston', 'San Diego', 'San Francisco']
                             })
      
      temp_table = test_df.reset_index().pivot_table(values = 'Value', index = ['Manufacturer', 'Metric', 'Sector'], aggfunc='sum')
      
      
      df_new = temp_table.reset_index()
      
      s1=df_new.set_index(['Manufacturer','Sector']).query("Metric=='Orders'").Value
      s2=df_new.set_index(['Manufacturer','Sector']).query("Metric=='Sales'").Value
      
      s1.div(s2).unstack().plot(kind='bar')
      

      感谢@YOBEN_S 提供原始数据集的解决方案并启发了这个解决方案!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-06-08
        • 2015-08-09
        • 2020-08-02
        • 2022-01-07
        • 2021-02-06
        • 1970-01-01
        • 2016-05-20
        • 2021-04-02
        相关资源
        最近更新 更多