我有一个巨大的数据帧df_original(1000万行)。索引是日期(多个相同的日期),有20行,但这里感兴趣的是公司。公司可能/可能不适用于每个日期。数据可追溯到10年前。
例如df_original:
Company
1/24/2007 Astec
1/24/2007 Abra
1/24/2007 Apple
1/24/2007 Acle ltd
1/24/2007 Apple ent
1/24/2007 Aztrazenca
1/24/2007 Alpha ltd
1/24/2007 Altit ltd
1/24/2007 Blackberry
1/24/2007 Burberry
1/24/2007 Blue ltd
1/24/2007 Bluefin
1/25/2017 Abra
1/25/2017 Apple
1/25/2017 Acle ltd
1/25/2017 Aztrazenca
1/25/2017 Altit ltd
1/25/2017 Blackberry
1/25/2017 Burberry
1/25/2017 Blue ltd
1/25/2017 Bluefin
现在我有另一张看起来像这样的桌子(实际上它要大得多)。这是公司评分变化的日期(不是每日频率,只要它发生变化):
df_grade_changes:
Date Company Grade
2/2/2017 Abra D
2/1/2017 Blue ltd B
1/21/2017 Blue fin C
1/1/2017 Aztrazenca B
12/10/2016 Altit ltd A
11/29/2016 Blackberry C
11/18/2016 Abra B
11/6/2016 Blue ltd A
我想在df_original中添加一行,每天使用df_grade_changes作为来源,每行都有一个等级。
即每当公司的成绩发生变化时,就会在df_original的病房中反映出来。关键是在Df_grade_changes中,成绩不是每天都在变化。
在上面的例子中使用df_grade_changes在2016年11月18日至2017年2月2日之前的1天,Abra会有B级,在无限期之后它将是D,除非它到达另一个等级变化。因此,我认为它可能需要从最旧到最新或从最新到最旧。
帮助将不胜感激。
答案 0 :(得分:2)
您可以使用pd.merge_asof
合并两个DataFrame:
# Set Date as the index of df_grade_changes and ensure that it's sorted.
df_grade_changes = df_grade_changes.set_index('Date').sort_index()
# Perform the merge_asof.
df = pd.merge_asof(df_original, df_grade_changes, left_index=True, right_index=True, by='Company')
使用示例数据的输出:
Company Grade
2007-01-24 Astec NaN
2007-01-24 Abra NaN
2007-01-24 Apple NaN
2007-01-24 Acle ltd NaN
2007-01-24 Apple ent NaN
2007-01-24 Aztrazenca NaN
2007-01-24 Alpha ltd NaN
2007-01-24 Altit ltd NaN
2007-01-24 Blackberry NaN
2007-01-24 Burberry NaN
2007-01-24 Blue ltd NaN
2007-01-24 Bluefin NaN
2017-01-25 Abra B
2017-01-25 Apple NaN
2017-01-25 Acle ltd NaN
2017-01-25 Aztrazenca B
2017-01-25 Altit ltd A
2017-01-25 Blackberry C
2017-01-25 Burberry NaN
2017-01-25 Blue ltd A
2017-01-25 Bluefin C
答案 1 :(得分:1)
注意:要使以下代码生效,您需要将df_original
中的日期索引转换为正确的“日期”列。
首先,在“公司”和“日期”上执行“外部”合并。
df_merge = df_original.merge(df_grade, how='outer', on=["company", "date"])
这样,您就可以在正确的日期添加df_grade_changes
到df_original
的已知成绩更改,同时保留与这两个数据框相关的所有数据。
接下来,您需要填写公司上一个已知成绩条目中的未知成绩条目。最简单的方法是定义一个函数,并使用split-apply-combine方法与Pandas groupby
。
def fill_grades_by_date(data):
# sort by date in ascending order
data.sort_values("date", ascending=True, inplace=True)
# fill unknown "grade" column entries using forward fill method
data["grade"] = data["grade"].fillna(method="ffill", inplace=False)
return data
# Implement split-apply-combine on df_merge:
# 1. splits into tables by company
# 2. applies function `fill_grades_by_date`
# 3. combines resulting groups back into a dataframe in the format of `df_merge`
df_result = df_merge.groupby("company").apply(fill_grades_by_date).reset_index(drop=True)