2016-03-28 133 views
1

我有两个大小不同的dataframes,我想用所有值的比较四种不同的列,(两套二)比较在dataframes

基本上我希望看​​到每一个值的列和行其中df1 ['A'] == df2 ['A'] &其中df1 ['B'] == df2 ['B']并且返回df1 ['C']的值加上df2 ['C']''价值观

import pandas as pd 
df1 = pd.DataFrame({"A": [1, 2, 3, 4, 3], "B": [2, 5, 4, 7, 5], "C": [1, 2, 8, 0, 0]}) 
df2 = pd.DataFrame({"A": [1, 3, 2, 4, 8], "B": [5, 5, 4, 9, 1], "C": [1, 3, 3, 4, 6]}) 


df1: 
    A B C 
0 1 2 1 
1 2 5 2 
2 3 4 8 
3 4 7 0 
4 3 5 0 
... 

df2: 
    A B C 
0 1 5 1 
1 3 4 3 
2 2 5 4 
3 4 9 4 
5 8 1 6 
... 

in: df1['A'] == df2['A'] & where df1['B'] == df2['B'] 
     df1['D'] = df1['C'] + df2['C'] 

out: df1: 
    A B C D 
0 1 2 1 nan 
1 2 5 2 6 
2 3 4 8 11 
3 4 7 0 nan 
4 3 5 0 nan 

我的实际dataframes大得多(数据的120000ish行与值两者“A”的列1至700和“B”从1到300的范围内),所以我知道它可能是一个较长的处理。

+0

我还想提一下,'A'两列中的数字重复了好几次,想起来更像是两组数据,一个列和一个行号专用于每个单元格,并且我需要在两个单元格相等处(两行相等且两列相等)进行数学计算,在这种情况下,我将它们分别命名为'A'和'B',但这是为了避免混淆,我确信我没有做得太好。 – rosskush

回答

0

你可以先合并两个dataframes

In [145]: dff = pd.merge(df1, df2, on=['A', 'B'], how='left') 

In [146]: dff 
Out[146]: 
    A B C_x C_y 
0 1 2 1 NaN 
1 2 5 2 4 
2 3 4 8 3 
3 4 7 0 NaN 

然后,采取C_-{like}列,其中空值不存在逐行总和,然后用零填充的NaN。

In [147]: dff['C'] = dff.filter(regex='C_').sum(skipna=False, axis=1).fillna(0) 

In [148]: dff 
Out[148]: 
    A B C_x C_y C 
0 1 2 1 NaN 0 
1 2 5 2 4 6 
2 3 4 8 3 11 
3 4 7 0 NaN 0 

而且,您可以删除/选择所需的列。

+0

感谢您的帮助,我明白您的意思,但我忘了提及的是,在df的专栏'A'和'B'专栏中,有很多重复的数字,从1-700到'A' 'B'为1-300。 – rosskush

0

既然你想保留的所有值从df1,做的df1df2左合并可以merge在列A和B两个DataFrames。在A和B不匹配的地方,合并的C列df2将为空。合并之后,这只是重命名合并列并进行总和的问题。

# Do a left merge, keeping df1 column names unchanged. 
df1 = pd.merge(df1, df2, how='left', on=['A', 'B'], suffixes=('', '_2')) 

# Add the two columns, fill locations that don't match with zero, and rename. 
df1['C_2'] = df1['C_2'].add(df1['C']).fillna(0) 
df1.rename(columns={'C_2': 'D'}, inplace=True)