大熊猫中的大数据,根据另一个表

时间:2017-02-14 21:53:33

标签: pandas group-by bigdata

我有一个巨大的数据帧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,除非它到达另一个等级变化。因此,我认为它可能需要从最旧到最新或从最新到最旧。

帮助将不胜感激。

2 个答案:

答案 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_changesdf_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)