【问题标题】:How to sumarize flattables using Python如何使用 Python 汇总平面表
【发布时间】:2016-09-04 13:42:23
【问题描述】:

我从 Excel 中读取了销售交易表,我很想知道在每个地点售出第一件商品后 1 小时内的销售数量。此外,我想知道其中有多少是用卡和现金购买的/ 设 A 为销售报表,我要创建 B。

A=
item    Location    Time        Payment
X       Canada      10:03:18    CreditC
X       Canada      10:08:38    Cash
X       Canada      10:24:46    Cash
X       Canada      11:16:35    Cash
X       US          10:00:16    Cash
X       US          11:52:12    CreditC
Y       Canada      2:08:38     CreditC
Y       Canada      4:01:48     Cash
Y       US          13:32:02    CreditC
Y       US          14:07:03    Cash

item    location    first sale  count   CreditCard  Cash
X       Canada      10:03:18    3       1           2
X       US          10:00:16    1       0           1
Y       Canada      2:08:38     1       1           0
Y       US          13:32:02    2       1           1

我这样做在第 6 行和第 9 行中出现错误。我已经编写了一些解决方法来完成这项工作,但我想了解什么是最好的方法。

#group the transactions within the time interval
df['start'] = pd.to_datetime(df['Time'])
grouped = df.groupby(['item', 'Location', 'Time'])
df['end'] = (grouped['start'].transform(lambda grp: grp.min()+pd.Timedelta(minutes=interval)))
df['count'] = (df['start'] < df['end'])
df['CreditCard'] = (df.Payment.map(len) == 7 and df['start'] < df['end'])

Summary =  pd.DataFrame(grouped['count'].sum()).reset_index()
Summary['CreditCard']=pd.Sereis(grouped['CreditCard'].sum(), index=Summary.index)  

【问题讨论】:

    标签: python pandas dataframe group-by grouping


    【解决方案1】:

    您可以使用pd.crosstab 生成频率表:

    import numpy as np
    import pandas as pd
    
    df = pd.DataFrame({'Location': ['Canada', 'Canada', 'Canada', 'Canada', 'US', 'US', 'Canada', 'Canada', 'US', 'US'], 'Payment': ['CreditC', 'Cash', 'Cash', 'Cash', 'Cash', 'CreditC', 'CreditC', 'Cash', 'CreditC', 'Cash'], 'Time': ['10:03:18', '10:08:38', '10:24:46', '11:16:35', '10:00:16', '11:52:12', '2:08:38', '4:01:48', '13:32:02', '14:07:03'], 'item': ['X', 'X', 'X', 'X', 'X', 'X', 'Y', 'Y', 'Y', 'Y']}) 
    
    df['start'] = pd.to_datetime(df['Time'])
    grouped = df.groupby(['item', 'Location'])
    interval = 60
    df['end'] = (grouped['start'].transform(lambda grp: grp.min()+pd.Timedelta(minutes=interval)))
    
    # isolate just the rows where the transaction occurs within an hour of first sale
    df2 = df.loc[(df['start'] < df['end'])]
    result = pd.crosstab(index=[df2['item'], df2['Location']], columns=[df2['Payment']])
    result['count'] = result['Cash'] + result['CreditC']
    result['first sale'] = grouped['Time'].first()
    

    产量

    Payment        Cash  CreditC  count first sale
    item Location                                 
    X    Canada       2        1      3   10:03:18
         US           1        0      1   10:00:16
    Y    Canada       0        1      1    2:08:38
         US           1        1      2   13:32:02
    

    【讨论】:

      【解决方案2】:
      interval = 60  # minutes
      df.sort_values('Time', inplace=True)
      gb = df.groupby(['item', 'Location'], sort=False).apply(
          lambda group: group[group.Time <= 
                              group.Time.iat[0] + pd.Timedelta(minutes=interval)].Payment)
      gb = gb.reset_index().groupby(['item', 'Location']).Payment.value_counts()
      gb = gb.unstack('Payment').fillna(0)
      gb['count'] = gb.sum(axis=1)
      >>> gb
      
      Payment        Cash  CreditC  count
      item Location                      
      X    Canada       2        1      3
           US           1        0      1
      Y    Canada       0        1      1
           US           1        1      2
      

      【讨论】:

        【解决方案3】:

        解决方案

        import datetime as dt
        
        def first_hour(x):
            start = x.iloc[0]['Time']
            end = start + dt.timedelta(hours=1)
            df = x[(start <= x.Time) & (x.Time <= end)].groupby('Payment').count().T
            df['count'] = df.sum()
            df['first sale'] = start
            return df.iloc[[0]]
        
        B = A.groupby(['item', 'Location']).apply(first_hour).fillna(0)
        
        B = B.reset_index()[['item', 'Location', 'first sale', 'count', 'CreditC', 'Cash']]
        
          item Location          first sale  count  CreditC  Cash
        0    X   Canada 2016-05-09 10:03:18    0.0      1.0   2.0
        1    X       US 2016-05-09 10:00:16    0.0      0.0   1.0
        2    Y   Canada 2016-05-09 02:08:38    0.0      1.0   0.0
        3    Y       US 2016-05-09 13:32:02    0.0      1.0   1.0
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-05-09
          • 2022-01-24
          • 2020-10-17
          • 1970-01-01
          • 2019-06-01
          • 2023-03-13
          相关资源
          最近更新 更多