2015-03-03 2 views
3

Я пытаюсь объединить dataframe (df1) с другим dataframe (df2), для которого df2 может быть пустым. Условие слияния - df1.index=df2.z (df1 никогда не пусто), но я получаю следующую ошибку.Слияние с пустым DataFrame

Есть ли способ получить эту работу?

In [31]: 
import pandas as pd 
In [32]: 
df1 = pd.DataFrame({'a': [1, 2, 3], 'b': [4, 5, 6], 'c': [1, 2, 3]}) 
df2 = pd.DataFrame({'x':[], 'y':[], 'z':[]}) 
dfm = pd.merge(df1, df2, how='outer', left_index=True, right_on='z') 
--------------------------------------------------------------------------- 
IndexError        Traceback (most recent call last) 
<ipython-input-34-4e9943198dae> in <module>() 
----> 1 dfmb = pd.merge(df1, df2, how='outer', left_index=True, right_on='z') 

/usr/local/lib/python2.7/dist-packages/pandas/tools/merge.pyc in merge(left, right, how, on, left_on, right_on, left_index, right_index, sort, suffixes, copy) 
    37       right_index=right_index, sort=sort, suffixes=suffixes, 
    38       copy=copy) 
---> 39  return op.get_result() 
    40 if __debug__: 
    41  merge.__doc__ = _merge_doc % '\nleft : DataFrame' 

/usr/local/lib/python2.7/dist-packages/pandas/tools/merge.pyc in get_result(self) 
    185 
    186  def get_result(self): 
--> 187   join_index, left_indexer, right_indexer = self._get_join_info() 
    188 
    189   ldata, rdata = self.left._data, self.right._data 

/usr/local/lib/python2.7/dist-packages/pandas/tools/merge.pyc in _get_join_info(self) 
    277     join_index = self.left.index.take(left_indexer) 
    278    elif self.left_index: 
--> 279     join_index = self.right.index.take(right_indexer) 
    280    else: 
    281     join_index = Index(np.arange(len(left_indexer))) 

/usr/local/lib/python2.7/dist-packages/pandas/core/index.pyc in take(self, indexer, axis) 
    981 
    982   indexer = com._ensure_platform_int(indexer) 
--> 983   taken = np.array(self).take(indexer) 
    984 
    985   # by definition cannot propogate freq 

IndexError: cannot do a non-empty take from an empty axes. 
+0

Почему бы просто не проверить, сначала ли пуст? что совсем не занимает времени –

+0

Это не проблема. В следующем коде я ожидаю объединенную структуру данных с столбцами из 'df1' и' df2' (хотя некоторые из них могут быть None/nan). – orange

ответ

0

Другой альтернативой, подобно Joran-х:

try: 
    dfm = pd.merge(df1, df2, how='outer', left_index=True, right_on='z') 
except IndexError: 
    dfm = df1.reindex_axis(df1.columns.union(df2.columns), axis=1) 

Я не уверен, что понятнее, но и следующие работы:

In [11]: df1.reindex_axis(df1.columns.union(df2.columns), axis=1) 
Out[11]: 
    a b c x y z 
0 1 4 1 NaN NaN NaN 
1 2 5 2 NaN NaN NaN 
2 3 6 3 NaN NaN NaN 

In [12]: df1.loc[:, df1.columns.union(df2.columns)] 
Out[12]: 
    a b c x y z 
0 1 4 1 NaN NaN NaN 
1 2 5 2 NaN NaN NaN 
2 3 6 3 NaN NaN NaN 

(I предпочитают первое.)

+0

Это прекрасно работает, но как я могу сохранить тип? 'union' просто копирует имена столбцов, но не тип. В моем случае некоторые из значений являются datetimes, поэтому я ожидал бы NaT вместо NaN в качестве значения столбца. – orange

+0

@orange Я бы просто ударил эти столбцы с помощью 'pd.to_datetime' впоследствии. –

+0

Да, вот что я в итоге сделал ... – orange

0
try: 
    dfm = pd.merge(df1, df2, how='outer', left_index=True, right_on='z') 
except IndexError: 
    dfm = df1 if not df1.empty else df2 

может быть достаточно для ваших нужд

+0

Это не то же самое, что слияние. После слияния я бы ожидал, что все столбцы будут частью 'dfm'. – orange

Смежные вопросы