pandas 中的大数据,基于另一张表匹配和回填/转发一张表
Posted
技术标签:
【中文标题】pandas 中的大数据,基于另一张表匹配和回填/转发一张表【英文标题】:Big data in pandas, matching and backfilling/forwardfilled one table based on another table 【发布时间】:2017-02-14 21:53:32 【问题描述】:我有一个巨大的数据框 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。所以我相信它可能必须从最旧到最新或从最新到最旧。
我们将不胜感激。
【问题讨论】:
【参考方案1】:您可以使用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
【讨论】:
【参考方案2】:注意:要使下面的代码正常工作,您需要将df_original
中的日期索引转换为适当的“日期”列。
首先,对“公司”和“日期”执行“外部”合并。
df_merge = df_original.merge(df_grade, how='outer', on=["company", "date"])
这允许您在正确的日期添加从 df_grade_changes
到 df_original
的已知成绩更改,同时保留与两个数据框相关联的所有数据。
接下来,您需要从公司的最后一个已知成绩条目中填写未知成绩条目。使用 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)
【讨论】:
以上是关于pandas 中的大数据,基于另一张表匹配和回填/转发一张表的主要内容,如果未能解决你的问题,请参考以下文章