按多列分组并在for循环中返回一列的SUM

时间:2017-10-21 12:09:40

标签: python pandas csv pandas-groupby

  • 我有一个包含许多列的csv文件。对于此处的示例,我总共使用了6列:

enter image description here

  • 我正在使用Python3和Pandas(我不熟悉)。

  • 我的主要目标是在烘焙当前数据后创建一个新的csv文件(如上所示)。我想分步做什么:

01)聚合数据:首先,按ID对行进行分组,并具有:

  1. 每个 ID的最早开始日期

  2. 每个 ID的最新结束日期

  3. 每个 ID

  4. 的值的总和

    02)对每个ID以及我选择的任何随机列进行分组:

    1. 每个 ID的最早开始日期

    2. 每个 ID的最新结束日期

    3. 每个 ID

    4. 的值的总和
    5. Random1 Random2 值与其他数据一起显示(已分组)

    6. 在不对数据进行分组的情况下,我能够获得最早的开始日期,最新的结束日期以及的总和。代码如下(1个ID):

      #Get the first Start Date
      minStartDate = df.loc[ df['ID'] == 56886, 'Start Date'].min()
      
      #Get the last End Date
      maxEndDate = df.loc[ df['ID'] == 56886, 'End Date'].max()
      
      #Get the value sum
      sumValue = df.loc[ df['ID'] == 56886, 'Value'].sum()
      

      然后我按所有ID对其进行分组:

      for i in ID:
          #Get the first Start Date
          minStartDate = df.loc[ df['ID'] == i, 'Start Date'].min()
          #Get the last End Date
          maxEndDate = df.loc[ df['ID'] == i, 'End Date'].max()
          #Get the Value sum
          sumValue = df.loc[ df['ID'] == i, 'Value'].sum()
      
      print(maxEndDate)
      

      我在打印后获得了 maxEndDate minStartDate sumValue ID 的正确值。问题是它只显示一个 ID 的值(文件中的最后一个):

      在这种情况下,这是预期的输出(在忽略Random列之后):

      enter image description here

      所以,我已将脚本改为:

      minStartDate = {}
      maxEndDate = {}
      summyValue = {}
      Key = {}
      ID = df[' ID']
      
      for i in ID:
          Key[i] = df.loc[ df['ID'] == i, 'ID']
          #Get the first Start Date
          minStartDate[i] = df.loc[ df['ID'] == i, 'Start Date'].min()
          #Get the last End Date
          maxEndDate[i] = df.loc[ df['ID'] == i, 'End Date'].max()
          #Get the Value sum
          summyValue[i] = df.loc[ df['ID'] == i, 'Value'].sum()
      
      
      
      print(summyValue,minStartDate,maxEndDate)
      

      在终端我得到了这个:

      enter image description here

      考虑到最终的预期输出是:

      enter image description here

      我应该怎样玩这些领域的组合?在for循环中,我猜我应该包括 Random 1 Random 2 列(密钥创建)。另外,为了在新的CSV文件中导出所有内容,for循环的最佳输出是什么?

1 个答案:

答案 0 :(得分:1)

如果你想用最大的重复值填充随机1和random2,那么你可以用你自己的函数使用agg,例如

df = pd.DataFrame({
    'id': [1,1,1,1,2,2,2],
    'r1': ['x','y','y','y','x','x','x'],
    'r2': ['t','I','t','t','c','c','c']
})

def max_rep(x):
    return x.value_counts().idxmax()

ndf = df.groupby('id',as_index=False).agg({'r1': max_rep,'r2':max_rep})

或如果你想在一行中使用lambda

ndf = df.groupby('id',as_index=False).agg({'r1': lambda x: x.value_counts().idxmax(),'r2': lambda x: x.value_counts().idxmax()})

输出:

  id r1 r2
0   1  y  t
1   2  x  c

如Jon所说,你可以使用聚合

在一行中完成所有步骤
df.groupby('ID',as_index=False).agg('Start Date': 'min', 'End Date': 'max', 'Value': 'sum', \
                 'Random 1':max_rep,'Random 2':max_rep})

如果您希望与random1和random2一起分组,那么您可以使用

df.groupby(['ID','Random 1','Random 2'],as_index=False).agg('Start Date': 'min', 'End Date': 'max', 'Value': 'sum')