Pandas 映射 2 个数据帧中的值和外连接 + 聚合值

Posted

技术标签:

【中文标题】Pandas 映射 2 个数据帧中的值和外连接 + 聚合值【英文标题】:Pandas mapping values in 2 dataframes and outer-join + aggregate values 【发布时间】:2020-06-08 19:55:25 【问题描述】:

您好,我有这两个数据框

df_1
title      URL  number         date
    a   /url-1       1   21-02-2020
    a   /url-1      10   20-02-2020
    a   /url-1      17   18-02-2020
    b   /url-2     100   21-02-2020
    b   /url-2     106   20-02-2020
df_2
   URL  number         date
/url-1       5   21-02-2020
/url-1      12   20-02-2020
/url-1      50   19-02-2020
/url-2      71   17-02-2020
/url-3       9   21-02-2020
/url-3      11   20-02-2020

所以我需要执行这些 Actions 将它们组合成 1 个数据框:

1) 添加新列调用 df_2["title"] 以将 df_2["URL"] 值映射到 df_1["title"] 中的值

2) 将两个数据框外连接在一起

3) 按“日期”聚合 df_1["number"] 和 df_2["number"] 并将它们相加

这是我想要的结果:

new_df
title      URL  number         date
    a   /url-1       6   21-02-2020
    a   /url-1      22   20-02-2020
    a   /url-1      50   19-02-2020
    a   /url-1      17   18-02-2020
    b   /url-2     100   21-02-2020
    b   /url-2     106   20-02-2020
    b   /url-2      71   17-02-2020
 null   /url-3       9   21-02-2020
 null   /url-3      11   20-02-2020

注意事项:

A) 我不能只在“URL”和“日期”上进行外部连接,因为您会注意到在 df_2;第 3 行(19-02-2020)中似乎没有相同的日期在 df_1 中表示“ /url-1”。同样的问题也适用于 df_2;第 4 行

B) 如果我能实现我对 new_df 的要求,我不介意跳过操作 1(如上图所示)

非常感谢您的帮助! :)

【问题讨论】:

【参考方案1】:

使用Series.mapDataFrame.drop_duplicates,然后新列用于外连接,最后一个sum 列:

df_2["title"] = df_2["URL"].map(df_1.drop_duplicates('URL').set_index('URL')["title"])

df = df_1.merge(df_2, on=['title','URL','date'], how='outer', suffixes=('','_'))
df['number'] = df['number'].add(df.pop('number_'), fill_value=0)
print (df)
  title     URL  number        date
0     a  /url-1     6.0  21-02-2020
1     a  /url-1    22.0  20-02-2020
2     a  /url-1    17.0  18-02-2020
3     b  /url-2   100.0  21-02-2020
4     b  /url-2   106.0  20-02-2020
5     a  /url-1    50.0  19-02-2020
6     b  /url-2    71.0  17-02-2020
7   NaN  /url-3     9.0  21-02-2020
8   NaN  /url-3    11.0  20-02-2020

必要时最后聚合sum - 因为缺失值是必要的,用一些非缺失值替换值:

df = (df.fillna('tmp')
         .groupby(['URL', 'date', 'title'], as_index=False)['number']
         .sum()
         .replace('tmp':np.nan)
         .reindex(df.columns, axis=1))

【讨论】:

刚回来定期回答关于 SO 的 python pandas 问题 2 年后,所有答案你仍然如此之快......:D @PhungDuyPhong - 嗯,这取决于。【参考方案2】:

将标题添加到 df2,然后附加,然后分组:

df2 = df2.merge(df1.loc[:, ['title', 'URL']].drop_duplicates(), on='URL', how='left')

df = df1.append(df2)

# group by auto exclude NaN value, so fillna with placeholder first
df.fillna('null').groupby(['URL', 'date', 'title']).sum().reset_index()

【讨论】:

以上是关于Pandas 映射 2 个数据帧中的值和外连接 + 聚合值的主要内容,如果未能解决你的问题,请参考以下文章

PYTHON Pandas - 根据其他数据帧中的值对数据帧使用 Pandas 样式

通过在两个 Pandas 数据帧之间迭代来识别相似的值。

Pandas 按行中的值和其他列中的值在行之间进行差异

python 存储在pandas数据帧中的几个变量之间的矩阵相关性

如何计算包含一组列中的值和 Pandas 数据框中另一列中的另一个值的行数?

如何根据一个数据帧中的列值和R中另一个数据帧的列标题名称有条件地创建新列