按多列分组和 for 循环中一列的 return SUM
Group by multple columns and return SUM of one column in a for loop
- 我有一个包含很多列的 csv 文件。对于这里的示例,我总共使用了 6 列:
我正在使用Python3和Pandas(我不是很熟悉)。
我的主要目标是在烘焙当前文件中的数据后创建一个新的 csv 文件(如上所示)。我想做的步骤:
01) 聚合数据:首先,按 ID 对行进行分组并具有:
每个ID
最早的开始日期
每个 ID
的最新结束日期
每个 ID
的值的总和
02) 将每个 ID 的行和我选择的任何随机列分组:
每个ID
最早的开始日期
每个 ID
的最新结束日期
每个 ID
的值的总和
显示 Random1 和 Random2 值以及其余数据(分组)
在不对数据进行分组的情况下,我能够得到最早的开始日期、最新的结束日期和值。代码如下(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(文件中的最后一个)的值:
在这种情况下,这是预期的输出(在忽略随机列之后):
因此,我已将脚本更改为:
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)
在终端我得到这个:
考虑到最终的预期输出是:
我应该如何使用这些字段的组合?在 for 循环中,我猜我应该包括 Random 1 和 Random 2 列(密钥创建)。此外,为了将所有内容导出到新的 CSV 文件中,for 循环的最佳输出是什么?
如果您想用最大重复值填充随机 1 和随机 2,那么您可以将 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 评论的那样,您可以使用 agg 在一行中完成所有步骤,即
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')
- 我有一个包含很多列的 csv 文件。对于这里的示例,我总共使用了 6 列:
我正在使用Python3和Pandas(我不是很熟悉)。
我的主要目标是在烘焙当前文件中的数据后创建一个新的 csv 文件(如上所示)。我想做的步骤:
01) 聚合数据:首先,按 ID 对行进行分组并具有:
每个ID
最早的开始日期
每个 ID
的最新结束日期
每个 ID
的值的总和
02) 将每个 ID 的行和我选择的任何随机列分组:
每个ID
最早的开始日期
每个 ID
的最新结束日期
每个 ID
的值的总和
显示 Random1 和 Random2 值以及其余数据(分组)
在不对数据进行分组的情况下,我能够得到最早的开始日期、最新的结束日期和值。代码如下(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(文件中的最后一个)的值:
在这种情况下,这是预期的输出(在忽略随机列之后):
因此,我已将脚本更改为:
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)
在终端我得到这个:
考虑到最终的预期输出是:
我应该如何使用这些字段的组合?在 for 循环中,我猜我应该包括 Random 1 和 Random 2 列(密钥创建)。此外,为了将所有内容导出到新的 CSV 文件中,for 循环的最佳输出是什么?
如果您想用最大重复值填充随机 1 和随机 2,那么您可以将 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 评论的那样,您可以使用 agg 在一行中完成所有步骤,即
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')