2017-04-04 84 views
2

我想连接两个数据帧,在上面和下面。不并排连接。熊猫:合并两个不同名称的列?

的dataframes包含相同的数据,但是,在第一数据帧一列可能有名为“对象类型”,并在第二个数据帧列中可能有名称“对象类”。当我做

df_total = pandas.concat ([df0, df1]) 

的df_total将有两个列名,一个以“对象类型”,另一个为“对象类”。在这两列中的每一列中,一半的值都是“NaN”。所以我必须手动将这两列合并成一个很痛苦的列。

我可以以某种方式将两列合并成一个?我想有一个功能,可以做类似于:

df_total = pandas.merge_many_columns(input=["ObjectType,"ObjectClass"], output=["MyObjectClasses"] 

它合并两列并创建一个新列。我已经研究过熔化(),但它并没有真正做到这一点?如果我可以指定碰撞时会发生什么,比如说两列包含值,那么我提供了一个lambda函数,指出“保持最大值”,“使用平均水平”,等等)

回答

2

我想你可以对齐数据都DataFrames第一重列:

df0 = pd.DataFrame({'ObjectType':[1,2,3], 
        'B':[4,5,6], 
        'C':[7,8,9]}) 

#print (df0) 

df1 = pd.DataFrame({'ObjectClass':[1,2,3], 
        'B':[4,5,6], 
        'C':[7,8,9]}) 

#print (df1) 

inputs= ["ObjectType","ObjectClass"] 
output= "MyObjectClasses" 

#dict comprehension 
d = {x:output for x in inputs} 
print (d) 
{'ObjectType': 'MyObjectClasses', 'ObjectClass': 'MyObjectClasses'} 

df0 = df0.rename(columns=d) 
df1 = df1.rename(columns=d) 
df_total = pd.concat([df0, df1], ignore_index=True) 
print (df_total) 
    B C MyObjectClasses 
0 4 7    1 
1 5 8    2 
2 6 9    3 
3 4 7    1 
4 5 8    2 
5 6 9    3 

编辑:

更多simplier是update(工作inplace):

df = pd.concat([df0, df1]) 
df['ObjectType'].update(df['ObjectClass']) 
print (df) 
    B C ObjectClass ObjectType 
0 4 7   NaN   1.0 
1 5 8   NaN   2.0 
2 6 9   NaN   3.0 
0 4 7   1.0   1.0 
1 5 8   2.0   2.0 
2 6 9   3.0   3.0 

或者fillna,但随后需要滴原列列:

df = pd.concat([df0, df1]) 
df["ObjectType"] = df['ObjectType'].fillna(df['ObjectClass']) 
df = df.drop('ObjectClass', axis=1) 
print (df) 
    B C ObjectType 
0 4 7   1.0 
1 5 8   2.0 
2 6 9   3.0 
0 4 7   1.0 
1 5 8   2.0 
2 6 9   3.0 

df = pd.concat([df0, df1]) 
df["MyObjectClasses"] = df['ObjectType'].fillna(df['ObjectClass']) 
df = df.drop(['ObjectType','ObjectClass'], axis=1) 
print (df) 
    B C MyObjectClasses 
0 4 7    1.0 
1 5 8    2.0 
2 6 9    3.0 
0 4 7    1.0 
1 5 8    2.0 
2 6 9    3.0 

EDIT1:

时序

df0 = pd.DataFrame({'ObjectType':[1,2,3], 
        'B':[4,5,6], 
        'C':[7,8,9]}) 

#print (df0) 

df1 = pd.DataFrame({'ObjectClass':[1,2,3], 
        'B':[4,5,6], 
        'C':[7,8,9]}) 

#print (df1) 
df0 = pd.concat([df0]*1000).reset_index(drop=True) 
df1 = pd.concat([df1]*1000).reset_index(drop=True) 

inputs= ["ObjectType","ObjectClass"] 
output= "MyObjectClasses" 

#dict comprehension 
d = {x:output for x in inputs} 

In [241]: %timeit df_total = pd.concat([df0.rename(columns=d), df1.rename(columns=d)], ignore_index=True) 
1000 loops, best of 3: 821 µs per loop 

In [240]: %%timeit 
    ...: df = pd.concat([df0, df1]) 
    ...: df['ObjectType'].update(df['ObjectClass']) 
    ...: df = df.drop(['ObjectType','ObjectClass'], axis=1) 
    ...: 

100 loops, best of 3: 2.18 ms per loop 

In [242]: %%timeit 
    ...: df = pd.concat([df0, df1]) 
    ...: df['MyObjectClasses'] = df['ObjectType'].combine_first(df['ObjectClass']) 
    ...: df = df.drop(['ObjectType','ObjectClass'], axis=1) 
    ...: 
100 loops, best of 3: 2.21 ms per loop 

In [243]: %%timeit 
    ...: df = pd.concat([df0, df1]) 
    ...: df['MyObjectClasses'] = df['ObjectType'].fillna(df['ObjectClass']) 
    ...: df = df.drop(['ObjectType','ObjectClass'], axis=1) 
    ...: 
100 loops, best of 3: 2.28 ms per loop 
+0

是这可能工作合并由南的分成一个两列。但是,我有很多列,我只想重命名两列。当数据帧有两列时,您的解决方案是否可用? –

+0

我认为这是通用的解决方案 - 在两个数据框中只需要相同的列名称。 – jezrael

+0

Thanx为您提供帮助,但我选择了“combine_first”的答案,因为它更简单。 :) –

1

可以使用combine_first

>>> import numpy as np 
>>> import pandas as pd 
>>> 
>>> df0 = pd.DataFrame({'ObjectType':[1,2,3], 
        'B':[4,5,6], 
        'C':[7,8,9]}) 

>>> df1 = pd.DataFrame({'ObjectClass':[1,2,3], 
        'B':[4,5,6], 
        'C':[7,8,9]}) 

>>> df = pd.concat([df0, df1]) 
>>> df['ObjectType'] = df['ObjectType'].combine_first(df['ObjectClass']) 
>>> df['ObjectType'] 

0 1 
1 2 
2 3 
0 1 
1 2 
3 3 
Name: ObjectType, dtype: float64 
+0

正如我所理解的那样,他在连接后得到了充满Nan's的df,现在正在寻找合并两列的方法。 – greole

+0

这正是我之后的事情。感谢名单!也许你可以编辑最后一行,而不是?我花了15分钟来解决这个问题,所以我希望能够加入: df [“ObjectType”] = df ['ObjectType']。combine_first(df ['ObjectClass']) –

+0

对不起,但我想“update()”比“combine_first()”稍微pythonic更多。我想选择这两种解决方案。 –