我有一个带有捐赠信息的熊猫数据框,如下所示:
DonorID DonationID Date Amount
a1234 3767 1/1/2019 $100
a1234 2193 2/1/2019 $50
a1234 0915 3/1/2019 $75
b5678 4562 5/1/2019 $45
b5678 8965 4/1/2019 $80
我正在使用groupby函数来计算每个DonorID和最短日期的总数,但还想通过DonorID计算最早的捐赠和DonationID的数量。
df2 = df1.groupby(['DonorID'], as_index=False ).agg( {'Amount':sum,'Date':min})
当前输出为:
DonorID Amount Date
a1234 $225 1/1/2019
b5678 $125 4/1/2019
所需的输出如下:
DonorID Amount Date First Gift Amount DonationID
a1234 $225 1/1/2019 $100 3767
b5678 $125 4/1/2019 $80 8965
任何帮助将不胜感激!
答案 0 :(得分:1)
您可能想要这样的东西:
df.sort_values('Date').groupby(['DonorID'], as_index=False)\
.agg({'Amount':['sum', 'first'], 'Date': 'min', 'DonationID': 'first'})
答案 1 :(得分:1)
有两种方法可以解决这个问题。
"date"
列上对数据框进行排序。这样可以确保在使用聚合方法"first"
时,您将获得与最小日期相对应的任何值。df2 = (df1
.sort_values("Date")
.groupby(["DonorID"], as_index=False)
.agg(
amount=("Amount", "sum"),
date=("Date", "min"),
first_amount=("Amount", "first"),
donation_id=("DonationID", "first"))
)
print(df2)
DonorID amount date first_amount donation_id
0 a1234 225 2019-01-01 100 3767
1 b5678 125 2019-04-01 80 8965
sort_values
(无论出于何种原因)。您可以分配一个临时列以获取idxmin()
列中的"Date"
。然后,您可以使用map
从原始数据框中提取相关值:df2 = (df1
.groupby(["DonorID"], as_index=False)
.agg(
amount=("Amount", "sum"),
date=("Date", "min"),
min_date_idx=("Date", "idxmin"))
.assign(
first_amount=lambda d: d["min_date_idx"].map(df1["Amount"]),
donation_id=lambda d: d["min_date_idx"].map(df1["DonationID"])
))
print(df2)
DonorID amount date min_date_idx first_amount donation_id
0 a1234 225 2019-01-01 0 100 3767
1 b5678 125 2019-04-01 4 80 8965
答案 2 :(得分:0)
这是使用agg()
方法并解压缩字典的一种方法。这样,您就可以在其中包含空格的列名称。
df['Date'] = pd.to_datetime(df['Date'])
df['Amount'] = df['Amount'].str.replace('$','')
df['Amount'] = pd.to_numeric(df['Amount'])
df.sort_values(by='Date',ascending=True).groupby('DonorID').agg(**{'Amount': ('Amount','sum'),'Date':('Date','first'),'First Gift Amount': ('Amount','first'),'DonationID':('DonationID','first')})