2017-01-17 8 views
3

Слияние двух фреймов данных: у меня есть два кадра данных, которые необходимо слить по некоторым критериям, но я не смог выяснить, как это сделать?Объединение Dataframes с разными именами столбцов с агрегированными значениями столбцов

df1 : 

id   positive_action date    volume 
id_1   user 1     2016-12-12  19720.735 
       user 2     2016-12-12  14740.800 

df2 : 
id   negative_action  date    volume 
id_1   user 1     2016-12-12  10.000 
       user 3     2016-12-12  10.000  

I want : 

id   action  date    volume 
id_1   user 1   2016-12-12  19730.735 
       user 2   2016-12-12  14740.800 
       user 3   2016-12-12  10.000 

Здесь

  1. Объем агрегируется на обоих dataframes
  2. слившихся на ID, дата и (позитивные действия и негативное действие слиты вместе)

Как я этого добиться?

ответ

2

Вы также можете объединить ваши DataFrames после переименования positive_action и negative_action столбцы просто action, а затем выполнить GroupBy.

df1.rename(columns={'positive_action':'action'}, inplace=True) 
df2.rename(columns={'negative_action':'action'}, inplace=True) 
pd.concat([df1, df2]).groupby(['id', 'action', 'date']).sum().reset_index() 


    id action  date  volume 
0 id_1 user 1 2016-12-12 19730.735 
1 id_1 user 2 2016-12-12 14740.800 
2 id_1 user 3 2016-12-12  10.000 
2

Это должно работать:

# not sure what indexing you are using so lets remove it 
# to get on the same page, so to speak ;). 
df1 = df1.reset_index() 
df2 = df2.reset_index() 

# do an outer merge to allow mismatches on the actions. 
df = df1.merge(
    df2, left_on=['id', 'positive_action', 'date'], 
    right_on=['id', 'negative_action', 'date'], 
    how='outer', 
) 


# fill the missing actions from one with the other. 
# (Will only happen when one is missing due to the way we merged.) 
df['action'] = df['positive_action'].fillna(df['negative_action']) 

# drop the old actions 
df = df.drop('positive_action', 1) 
df = df.drop('negative_action', 1) 

# aggregate the volumes (I'm assuming you mean a simple sum) 
df['volume'] = df['volume_x'].fillna(0) + df['volume_y'].fillna(0) 

# drop the old volumes 
df = df.drop('volume_x', 1) 
df = df.drop('volume_y', 1) 

print(df) 

Выход:

 id  date  volume action 
0 id_1 2016-12-12 19730.735 user_1 
1 id_1 2016-12-12 14740.800 user_2 
2 id_1 2016-12-12  10.000 user_3 

Вы можете восстановить индексирование я, возможно, удалены.

2
  • set_index на колоннах, которые вы хотите «слить» на
  • rename_axis потому что, когда мы add если мы непоследовательно назвали уровни индекса, он будет делать панда крик.
  • использование pd.Series.add с параметром fill_value=0
  • rename_axis снова с нужными именами
  • reset_index и вы в бизнесе

v1 = df1.set_index(['positive_action', 'date']).volume.rename_axis([None, None]) 
v2 = df2.set_index(['negative_action', 'date']).volume.rename_axis([None, None]) 
v1.add(v2, fill_value=0).rename_axis(['action', 'date']).reset_index() 

    action  date  volume 
0 user 1 2016-12-12 19730.735 
1 user 2 2016-12-12 14740.800 
2 user 3 2016-12-12  10.000 

установки

df1 = pd.DataFrame(dict(
     positive_action=['user 1', 'user 2'], 
     date=pd.to_datetime(['2016-12-12', '2016-12-12']), 
     volume=[19720.735, 14740.800] 
    )) 

df2 = pd.DataFrame(dict(
     negative_action=['user 1', 'user 3'], 
     date=pd.to_datetime(['2016-12-12', '2016-12-12']), 
     volume=[10, 10] 
    )) 
Смежные вопросы