【问题标题】:How to consolidate/divide rows within a data frame based on a value within a certain column using pandas?如何使用熊猫根据某列中的值合并/划分数据框中的行?
【发布时间】:2022-01-21 15:47:20
【问题描述】:

起始df如下:

company  metric  time   data
x        X10384  M1     100
x        X10384  M2     100
x        X10384  M3     100
y        X10456  M4     200
y        X10456  M5     200
y        X10456  M6     200

我需要能够根据时间维度的值合并这些行。基本上“M1、M2、M3”将包含 Q1,“M4、M5、M6”将包含 Q2,依此类推。

生成的 df 需要如下所示:

company  metric  time   data
x        X10384  Q1     300
y        X10456  Q2     600

同样,如果从 df 开始,我将需要能够将时间分成几个月并将数据分成相等的三个,就像在初始 df 中一样。

如何尝试像上面那样转换这些数据?以下是我的参考起点:

quarters = ['Q1', 'Q2']
months = ['M1','M2','M3','M4','M5','M6']

for time in df['time']:
    if time in quarters:
        [insert transformation into individual months]
    elif time in months:
        [insert transformation into quarters]

【问题讨论】:

    标签: python pandas list dataframe


    【解决方案1】:

    time 列中提取数字,然后将它们转换为季度数字。最后,一个简单的groupby_sum 完成这项工作:

    # Convert M1, M2, M3, M4, M5, M6 to Q1, Q1, Q1, Q2, Q2, Q2
    to_quarter = df['time'].str[1:].astype(int).floordiv(4).add(1).astype(str).radd('Q')
    
    out = df.assign(time=to_quarter).groupby(['company', 'metric', 'time']) \
                                    .sum().reset_index()
    

    输出:

    >>> out
      company  metric time  data
    0       x  X10384   Q1   300
    1       y  X10456   Q2   600
    

    【讨论】:

    • 对于您的另一部分(季度到月)如何知道哪个月?
    【解决方案2】:

    根据您的数据创建数据框:

    data = {'Company' : ['x', 'x', 'x', 'y', 'y', 'y'],  
            'Metric' : ['X10384', 'X10384', 'X10384', 'X10456', 'X10456', 'X10456'],
            'time': ['M1', 'M2', 'M3', 'M4', 'M5', 'M6'],
            'data': [100, 100, 100, 200, 200, 200]}
    df = pd.DataFrame(data)
    

    然后创建字典并按时间映射:

    dict = {'M1': 'Q1', 'M2' : 'Q1', 'M3' : "Q1", 'M4' : 'Q2', 'M5' : 'Q2', 'M6' : 'Q2'}
    df['time'] = df['time'].map(dict)
    

    而groupby会给你最终的结果:

    df.groupby(['Company','Metric','time']).sum().reset_index()
    

    【讨论】:

    • +1 但您可以将as_index=False 传递给groupby 以在末尾不写reset_index;但如果您发现reset_index 更具可读性,恕我直言,这也是可以理解的。此外,将内置的dict 遮住,作为荧光笔信号,之后会使其无法使用。
    【解决方案3】:

    从几个月到几个季度

    输入

    company  metric  time   data
    x        X10384  M1     100
    x        X10384  M2     100
    x        X10384  M3     100
    y        X10456  M4     200
    y        X10456  M5     200
    y        X10456  M6     200
    

    创建一个以月为键的字典,以季度为值,并用键映射列

    months_to_quarters_dict = {'M1': 'Q1', 'M2' : 'Q1', 'M3' : "Q1", 'M4' : 'Q2', 'M5' : 'Q2', 'M6' : 'Q2'}
    df['time'] = df['time'].map(months_to_quarters_dict)
    

    输出 (1a)

    company  metric  time   data
    x        X10384  Q1     100
    x        X10384  Q1     100
    x        X10384  Q1     100
    y        X10456  Q2     200
    y        X10456  Q2     200
    y        X10456  Q2     200
    

    使用 groupby().agg('sum') 得到浓缩的 df

    df.groupby(['Company','Metric','time'], as_index=False).agg('sum')
    

    输出 (1b)

    company  metric  time   data
    x        X10384  Q1     300
    y        X10456  Q2     600
    

    从季度到月

    输入

    company  metric  time   data
    x        X10384  Q1     300
    y        X10456  Q2     600
    

    创建一个以季度为键的字典以获取以月为单位的值,并用键映射列

    quarters_to_months_dict = {'Q1' : ['M1', 'M2', 'M3'], 'Q2' : ['M4', 'M5', 'M6']}
    df['time'] = df['time'].map(months_to_quarters_dict)
    

    输出 (2a)

      company  metric time  data
    0       x  X10384   ['M1', 'M2', 'M3']   300
    1       y  X10456   ['M4', 'M5', 'M6']   600
    

    使用explode on time 列拆分行,然后将数据列除以3,得到一个季度每个月的相等数量

    df = df.explode('time')
    df['data'] = df['data].div(3)
    

    输出 (2b)

    company  metric  time   data
    x        X10384  M1     100
    x        X10384  M2     100
    x        X10384  M3     100
    y        X10456  M4     200
    y        X10456  M5     200
    y        X10456  M6     200
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-09-05
      • 1970-01-01
      • 1970-01-01
      • 2021-12-22
      • 2018-02-27
      • 2017-09-15
      • 2022-07-11
      • 1970-01-01
      相关资源
      最近更新 更多