【问题标题】:Split row based on column value根据列值拆分行
【发布时间】:2021-01-17 00:23:09
【问题描述】:

所以,我已经在这上面坐了很长时间(并且拉扯我的头发),并且非常感谢这里的一些帮助。我在这样的数据框中有一些聚合数据,

CLASS_ID,ACH_MONTH(MM format),ACH_YEAR(YYYY format),FEES,PAY_TYPE
862424,06,2020,1000,Month
862425,04,2020,10000,Quarter
862426,02,2020,60000,Bi-Annual

(a). 我想要做的是将一条记录分成 3 条,只要 PAY_TYPEQuarter,基于以下逻辑,

(i)。将费用除以季度中的月数,即 3。

(ii)。将结果作为新值 FEES 应用于所有 3 条拆分记录,ACH_MONTH 是每条记录所在季度的单独月份。

例如,

考虑第二条记录,

这里,ACH_MONTH 是 04,表示 2 季度出现的四月。

现在将 FEES 的值除以 3,即 10000/3 = 3333.33。

现在将记录拆分为 3,每个值 ACH_MONTH 表示 Quarter2 的每个相应月份,如下所示,

862425,04,2020,3333.33,Quarter
862425,05,2020,3333.33,Quarter
862425,06,2020,3333.33,Quarter

(b). 同样,每当PAY_TYPEBi-Annual 时,我必须将记录分成 6 个,每条记录的值都是 FEES,分别为 60000/6 = 10000 和 ACH_MONTH那个双年度的几个月。

例如,

考虑第三条记录,

这里,ACH_MONTH 是 02 表示 2 月,即今年上半年。

现在将FEES 的值除以 6,即 60000/6 = 10000。

现在将记录拆分为 6,每个值 ACH_MONTH 表示今年上半年的每个相应月份,如下所示,

862426,01,2020,10000,Bi-Annual
862426,02,2020,10000,Bi-Annual
862426,03,2020,10000,Bi-Annual
862426,04,2020,10000,Bi-Annual
862426,05,2020,10000,Bi-Annual
862426,06,2020,10000,Bi-Annual

基于上述输入数据帧的最终预期输出,

CLASS_ID,ACH_MONTH,ACH_YEAR,FEES,PAY_TYPE
862424,06,2020,1000,Month
862425,04,2020,3333.33,Quarter
862425,05,2020,3333.33,Quarter
862425,06,2020,3333.33,Quarter
862426,01,2020,10000,Bi-Annual
862426,02,2020,10000,Bi-Annual
862426,03,2020,10000,Bi-Annual
862426,04,2020,10000,Bi-Annual
862426,05,2020,10000,Bi-Annual
862426,06,2020,10000,Bi-Annual

季度参考,

January(01), February(02), March(03) -- (Q1)
April(04), May(05), June(06) -- (Q2)
July(07), August(08), September(09) -- (Q3)
October(10), November(11), December(12) -- (Q4)

双年度参考,

January(01), February(02), March(03), April(04), May(05), June(06) -- (H1)
July(07), August(08), September(09), October(10), November(11), December(12) -- (H2)

我们将不胜感激任何和所有的帮助。提前致谢。

【问题讨论】:

    标签: python pandas python-2.7


    【解决方案1】:

    希望我能正确理解约束

    从未使用过DataFrame,但如果您可以从字典或其他方式初始化DataFrame对象,这种方式应该可以工作

    # make mappings of both quarter and bi-annual
    quarters = {
      "Q1": ["01", "02", "03"],
      "Q2": ["04", "05", "06"],
      "Q3": ["07", "08", "09"],
      "Q4": ["10", "11", "12"],
    }
    
    biannual = {
      "B1": ["01", "02", "03", "04", "05", "06"],
      "B2": ["07", "08", "09", "10", "11", "12"]
    }
    
    # find matching biannual or quarters based on the month mapped on its values
    def find(ach_month, q_or_b):
      result = None
      for key in q_or_b:
        value = q_or_b[key]
        try:
          # check if the ach_month exists in current iteration, if not ValueError is raised
          value.index(ach_month)
          result = value
          break
        except ValueError:
          # if not found, proceed to next iteration
          pass
      # if the data is not normalized, it may returns None
      return result
    
    # returns list of new dataframe object if it satisfies the constraint
    def remap(obj):
      if obj.pay_type == "Quarter":
        quart = find(obj.ach_month, quarters)
        return [DataFrame({}) for q in quart]
      if obj.pay_type == "Bi-Annual":
        bian = find(obj.ach_month, biannual)
        return [DataFrame({}) for b in bian]
      return [obj] 
    

    {} 中填充了您想要的记录的新属性。

    【讨论】:

      【解决方案2】:

      想法是通过嵌套的dict理解为每个季度和两年创建2个字典,按PAY_TYPE过滤行并使用Series.map,然后将列除以36,最后使用DataFrame.explode

      q = [["01", "02", "03"],["04", "05", "06"],["07", "08", "09"],["10", "11", "12"]]
      dq = {y: tuple(x) for x in q for y in x}
      # print (dq)
      
      b = [["01", "02", "03", "04", "05", "06"],["07", "08", "09", "10", "11", "12"]]
      db = {y: tuple(x) for x in b for y in x}
      # print (db)
      
      m1 = df['PAY_TYPE'].eq('Quarter')
      df.loc[m1, 'ACH_MONTH'] = df.loc[m1, 'ACH_MONTH'].map(dq)
      df.loc[m1, 'FEES'] /= 3
      
      m2 = df['PAY_TYPE'].eq('Bi-Annual')
      df.loc[m2, 'ACH_MONTH'] = df.loc[m2, 'ACH_MONTH'].map(db)
      df.loc[m2, 'FEES'] /= 6
      
      df = df.explode('ACH_MONTH').reset_index(drop=True)
      

      print (df)
         CLASS_ID ACH_MONTH  ACH_YEAR          FEES   PAY_TYPE
      0    862424        06      2020   1000.000000      Month
      1    862425        04      2020   3333.333333    Quarter
      2    862425        05      2020   3333.333333    Quarter
      3    862425        06      2020   3333.333333    Quarter
      4    862426        01      2020  10000.000000  Bi-Annual
      5    862426        02      2020  10000.000000  Bi-Annual
      6    862426        03      2020  10000.000000  Bi-Annual
      7    862426        04      2020  10000.000000  Bi-Annual
      8    862426        05      2020  10000.000000  Bi-Annual
      9    862426        06      2020  10000.000000  Bi-Annual
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-02-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-14
        相关资源
        最近更新 更多