【发布时间】:2017-10-31 17:21:53
【问题描述】:
我正在尝试按 Pandas 中的 csv 文件(按一列:ID)进行分组,以获得最早的开始日期和最晚的结束日期。然后我试图按多列分组以获得一个值的总和。对于第二个 groupedby 数据框中的每个 ID,我想显示日期。
我正在加载 csv 以便对数据进行分组和汇总。
01) 首先我加载 csv
def get_csv():
#Read csv file
df = pd.read_csv('myFile.csv', encoding = "ISO-8859-1",parse_dates=['Start Date', 'End Date'])
return df
02) 对列(ID 和站点)的数据进行分组和聚合
def do_stuff():
df = get_csv()
groupedBy = df[df['A or B'].str.contains('AAAA')].groupby([df['ID'], df['Site'].fillna('Other'),]).agg({'Start Date': 'min', 'End Date': 'max', 'Value': 'sum'})
按预期工作,我得到以下(示例):
03) 理想情况下,对于相同的 ID,我想在“开始日期”列中显示最早的日期,在“结束日期”列中显示最新的日期。该值的聚合完美运行。我想要得到的是以下内容:
我不知道如何更改上面的当前代码。到目前为止我已经尝试过了:
def do_stuff():
df = get_csv()
md = get_csv()
minStart = md[md['A or B'].str.contains('AAAA')].groupby([md['ID']]).agg({'Start Date': 'min'})
df['earliestStartDate'] = minStart
groupedBy = df[df['A or B'].str.contains('AAAA')].groupby([df['ID'], df['Site'].fillna('Other'),df['earliestStartDate']]).agg({'Start Date': 'min', 'End Date': 'max', 'Value': 'sum'})
失败了,还尝试将上面的内容更改为:
def do_stuff():
df = get_csv()
md = get_csv()
df['earliestStartDate'] = md.loc[ md['ID'] == df['ID'], 'Start Date'].min()
groupedBy = df[df['A or B'].str.contains('AAAA')].groupby([df['ID'], df['Site'].fillna('Other'),df['earliestStartDate']]).agg({'Start Date': 'min', 'End Date': 'max', 'Value': 'sum'})
理想情况下,我只需更改 groupedBy 中的某些内容,而不必读取 csv 两次并聚合数据两次。那可能吗?如果没有,我可以更改什么以使脚本正常工作?我正在尝试测试随机事物以获得更多关于 Pandas 和 Python 的经验。
我猜我必须在这里创建两个dataframes。一种获取所需所有列的groupedby 数据(以及值的总和)。第二个获取每个 ID 的最早开始日期和最晚结束日期。然后我需要找到一种方法来连接两个dataframes。这是一个好的结果还是您认为有更简单的方法可以实现?
UPD:我创建了两个数据框的代码(不确定这是否是正确的解决方案)如下所示:
#Read csv file
df = pd.read_csv('myFile.csv', encoding = "ISO-8859-1",mangle_dupe_cols=True, parse_dates=['Start Date', 'End Date'])
md = pd.read_csv('myFile.csv', encoding = "ISO-8859-1",mangle_dupe_cols=True, parse_dates=['Start Date', 'End Date'])
#Calculate the Clean Value
df['Clean Cost'] = (df['Value'] - df['Value2']) #.apply(lambda x: round(x,0))
#Get the min/max Dates
minMaxDates = md[md['Random'].str.contains('Y')].groupby([md['ID']]).agg({'Start Date': 'min', 'End Date': 'max'})
#Group by and aggregate (return Earliest Start Date, Latest End Date and SUM of the Values)
groupedBy = df[df['Random'].str.contains('Y')].groupby([df['ID'], df['Site'].fillna('Other')]).agg({'Start Date': 'min', 'End Date': 'max', 'Value': 'sum', 'Value2': 'sum', 'Clean Cost': 'sum'})
如果我打印两个数据框,我会得到以下信息:
和
如果我打印 df.head(),我会得到以下信息:
ID A or B Start Date End Date Value Site Value2 Random alse.
0 45221 AAAA 2017-12-30 2017-09-30 14 S111 7 Y 1 45221 AAAA 2017-01-15 2017-09-30 15 S222 7 是 2 85293 BBBB 2017-05-12 2017-07-24 29 S111 3 Y 3 85293 AAAA 2017-03-22 2017-10-14 32 S222 4 Y 4 45221 AAAA 2017-01-15 2017-09-30 30 S222 7 是
这里给出了文件的链接:LINK
【问题讨论】:
-
您能否提供一个小样本数据框,足以复制您的代码?
-
@ASGM 我已经打印了 groupedby 和 minMaxDates。我已经更新了这个问题。够了吗?
-
您可以将其提供为代码而不是图像吗?如果有人可以复制粘贴您发布的代码,复制您的问题,然后找到解决方案,您就更有可能获得有用的答案。
-
@ASGM 我已经上传了文件。我还粘贴了 df.head() (这次不是图像)。让我知道一般情况下是否可以。