Pandas сопоставление значений в 2 фреймах данных и внешнем объединении + агрегатные значения - PullRequest
1 голос
/ 25 февраля 2020

Здравствуйте, у меня есть эти 2 кадра данных

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

Поэтому мне нужно выполнить эти Действия , чтобы объединить их в 1 кадр данных:

1) Добавить вызов нового столбца df_2 ["title"] для сопоставления значений df_2 ["URL"] со значениями в df_1 ["title"]

2) Внешнее объединение обоих фреймов данных

3) Агрегирование df_1 ["number"] и df_2 ["number"] по "date" и суммируем их вместе

Вот результат, который я хочу:

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) Я не против пропустить Действие 1 (как выделено выше), если я могу добиться того, что хочу для new_df

Ваша помощь высоко ценится! :)

Ответы [ 2 ]

2 голосов
/ 25 февраля 2020

Используйте Series.map с DataFrame.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))
1 голос
/ 25 февраля 2020

Добавьте заголовок к 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()
...