2017-04-04 57 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更多。我想選擇這兩種解決方案。 –