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_changesdf_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 中的大数据,基于另一张表匹配和回填/转发一张表的主要内容,如果未能解决你的问题,请参考以下文章

删除一张表中与另一张表中相同的记录

Mongo基于一张表的数据更新另一张表

如何从另一张表中获取完全匹配的数据?

Excel:VLOOKUP 将一列与另一张表匹配并连接数据

根据查找值将值从一张表匹配并粘贴到另一张表中

可以将行中的数据从一张纸复制到另一张纸吗?