@@ -226,9 +226,10 @@ exports.default = DataFrame;
226226var innerMerge = function innerMerge ( df1 , df2 , on ) {
227227 var data = [ ] ;
228228
229- var nonMergeCols1 = df1 . columns . filter ( function ( k ) {
230- return on . indexOf ( k ) < 0 ;
231- } ) ;
229+ var cols1 = ( 0 , _utils . nonMergeColumns ) ( df1 . columns , on ) ;
230+ var cols2 = ( 0 , _utils . nonMergeColumns ) ( df2 . columns , on ) ;
231+
232+ var intersectCols = ( 0 , _utils . intersectingColumns ) ( cols1 , cols2 ) ;
232233
233234 var _iteratorNormalCompletion = true ;
234235 var _didIteratorError = false ;
@@ -282,12 +283,21 @@ var innerMerge = function innerMerge(df1, df2, on) {
282283 if ( match ) {
283284 ( function ( ) {
284285 var rowData = { } ;
285- nonMergeCols1 . forEach ( function ( k ) {
286+
287+ on . forEach ( function ( k ) {
286288 rowData [ k ] = row1 [ k ] . iloc ( 0 ) ;
287289 } ) ;
288- df2 . columns . forEach ( function ( k ) {
289- rowData [ k ] = row2 [ k ] . iloc ( 0 ) ;
290+
291+ cols1 . forEach ( function ( k ) {
292+ var nextColName = intersectCols . length > 0 && intersectCols . indexOf ( k ) >= 0 ? k + '_x' : k ;
293+ rowData [ nextColName ] = row1 [ k ] . iloc ( 0 ) ;
290294 } ) ;
295+
296+ cols2 . forEach ( function ( k ) {
297+ var nextColName = intersectCols . length > 0 && intersectCols . indexOf ( k ) >= 0 ? k + '_y' : k ;
298+ rowData [ nextColName ] = row2 [ k ] . iloc ( 0 ) ;
299+ } ) ;
300+
291301 data . push ( rowData ) ;
292302 } ) ( ) ;
293303 }
@@ -333,6 +343,181 @@ var innerMerge = function innerMerge(df1, df2, on) {
333343 return new DataFrame ( data ) ;
334344} ;
335345
346+ /**
347+ * Perform an outer merge of two DataFrames
348+ *
349+ * @param {DataFrame } df1
350+ * @param {DataFrame } df2
351+ * @param {Array } on
352+ *
353+ * @returns {DataFrame }
354+ */
355+ var outerMerge = function outerMerge ( df1 , df2 , on ) {
356+ var data = [ ] ;
357+
358+ var cols1 = ( 0 , _utils . nonMergeColumns ) ( df1 . columns , on ) ;
359+ var cols2 = ( 0 , _utils . nonMergeColumns ) ( df2 . columns , on ) ;
360+
361+ var intersectCols = ( 0 , _utils . intersectingColumns ) ( cols1 , cols2 ) ;
362+
363+ var matched1 = new Array ( df1 . length ) . fill ( false ) ;
364+ var matched2 = new Array ( df2 . length ) . fill ( false ) ;
365+
366+ var _iteratorNormalCompletion4 = true ;
367+ var _didIteratorError4 = false ;
368+ var _iteratorError4 = undefined ;
369+
370+ try {
371+ var _loop4 = function _loop4 ( ) {
372+ var _step4$value = ( 0 , _slicedToArray3 . default ) ( _step4 . value , 2 ) ,
373+ row1 = _step4$value [ 0 ] ,
374+ idx_1 = _step4$value [ 1 ] ;
375+
376+ var _iteratorNormalCompletion5 = true ;
377+ var _didIteratorError5 = false ;
378+ var _iteratorError5 = undefined ;
379+
380+ try {
381+ var _loop5 = function _loop5 ( ) {
382+ var _step5$value = ( 0 , _slicedToArray3 . default ) ( _step5 . value , 2 ) ,
383+ row2 = _step5$value [ 0 ] ,
384+ idx_2 = _step5$value [ 1 ] ;
385+
386+ var match = true ;
387+ var _iteratorNormalCompletion6 = true ;
388+ var _didIteratorError6 = false ;
389+ var _iteratorError6 = undefined ;
390+
391+ try {
392+ for ( var _iterator6 = on [ Symbol . iterator ] ( ) , _step6 ; ! ( _iteratorNormalCompletion6 = ( _step6 = _iterator6 . next ( ) ) . done ) ; _iteratorNormalCompletion6 = true ) {
393+ var c = _step6 . value ;
394+
395+ if ( row1 [ c ] . iloc ( 0 ) !== row2 [ c ] . iloc ( 0 ) ) {
396+ match = false ;
397+ break ;
398+ }
399+ }
400+ } catch ( err ) {
401+ _didIteratorError6 = true ;
402+ _iteratorError6 = err ;
403+ } finally {
404+ try {
405+ if ( ! _iteratorNormalCompletion6 && _iterator6 . return ) {
406+ _iterator6 . return ( ) ;
407+ }
408+ } finally {
409+ if ( _didIteratorError6 ) {
410+ throw _iteratorError6 ;
411+ }
412+ }
413+ }
414+
415+ var rowData = { } ;
416+
417+ on . forEach ( function ( k ) {
418+ rowData [ k ] = row1 [ k ] . iloc ( 0 ) ;
419+ } ) ;
420+
421+ cols1 . forEach ( function ( k ) {
422+ var nextColName = intersectCols . length > 0 && intersectCols . indexOf ( k ) >= 0 ? k + '_x' : k ;
423+ rowData [ nextColName ] = row1 [ k ] . iloc ( 0 ) ;
424+ } ) ;
425+
426+ if ( match ) {
427+ cols2 . forEach ( function ( k ) {
428+ var nextColName = intersectCols . length > 0 && intersectCols . indexOf ( k ) >= 0 ? k + '_y' : k ;
429+ rowData [ nextColName ] = row2 [ k ] . iloc ( 0 ) ;
430+ } ) ;
431+ data . push ( rowData ) ;
432+ matched1 [ idx_1 ] = true ;
433+ matched2 [ idx_2 ] = true ;
434+ }
435+ } ;
436+
437+ for ( var _iterator5 = df2 . iterrows ( ) [ Symbol . iterator ] ( ) , _step5 ; ! ( _iteratorNormalCompletion5 = ( _step5 = _iterator5 . next ( ) ) . done ) ; _iteratorNormalCompletion5 = true ) {
438+ _loop5 ( ) ;
439+ }
440+ } catch ( err ) {
441+ _didIteratorError5 = true ;
442+ _iteratorError5 = err ;
443+ } finally {
444+ try {
445+ if ( ! _iteratorNormalCompletion5 && _iterator5 . return ) {
446+ _iterator5 . return ( ) ;
447+ }
448+ } finally {
449+ if ( _didIteratorError5 ) {
450+ throw _iteratorError5 ;
451+ }
452+ }
453+ }
454+ } ;
455+
456+ for ( var _iterator4 = df1 . iterrows ( ) [ Symbol . iterator ] ( ) , _step4 ; ! ( _iteratorNormalCompletion4 = ( _step4 = _iterator4 . next ( ) ) . done ) ; _iteratorNormalCompletion4 = true ) {
457+ _loop4 ( ) ;
458+ }
459+ } catch ( err ) {
460+ _didIteratorError4 = true ;
461+ _iteratorError4 = err ;
462+ } finally {
463+ try {
464+ if ( ! _iteratorNormalCompletion4 && _iterator4 . return ) {
465+ _iterator4 . return ( ) ;
466+ }
467+ } finally {
468+ if ( _didIteratorError4 ) {
469+ throw _iteratorError4 ;
470+ }
471+ }
472+ }
473+
474+ matched1 . forEach ( function ( m , idx ) {
475+ if ( ! m ) {
476+ ( function ( ) {
477+ var rowData = { } ;
478+ on . forEach ( function ( k ) {
479+ rowData [ k ] = df1 [ k ] . iloc ( idx ) ;
480+ } ) ;
481+
482+ cols1 . forEach ( function ( k ) {
483+ var nextColName = intersectCols . length > 0 && intersectCols . indexOf ( k ) >= 0 ? k + '_x' : k ;
484+ rowData [ nextColName ] = df1 [ k ] . iloc ( idx ) ;
485+ } ) ;
486+
487+ cols2 . forEach ( function ( k ) {
488+ var nextColName = intersectCols . length > 0 && intersectCols . indexOf ( k ) >= 0 ? k + '_y' : k ;
489+ rowData [ nextColName ] = null ;
490+ } ) ;
491+ data . push ( rowData ) ;
492+ } ) ( ) ;
493+ }
494+ } ) ;
495+
496+ matched2 . forEach ( function ( m , idx ) {
497+ if ( ! m ) {
498+ ( function ( ) {
499+ var rowData = { } ;
500+ on . forEach ( function ( k ) {
501+ rowData [ k ] = df2 [ k ] . iloc ( idx ) ;
502+ } ) ;
503+
504+ cols1 . forEach ( function ( k ) {
505+ var nextColName = intersectCols . length > 0 && intersectCols . indexOf ( k ) >= 0 ? k + '_x' : k ;
506+ rowData [ nextColName ] = null ;
507+ } ) ;
508+
509+ cols2 . forEach ( function ( k ) {
510+ var nextColName = intersectCols . length > 0 && intersectCols . indexOf ( k ) >= 0 ? k + '_y' : k ;
511+ rowData [ nextColName ] = df2 [ k ] . iloc ( idx ) ;
512+ } ) ;
513+ data . push ( rowData ) ;
514+ } ) ( ) ;
515+ }
516+ } ) ;
517+
518+ return new DataFrame ( data ) ;
519+ } ;
520+
336521/**
337522 * Perform a merge of two DataFrames
338523 *
@@ -364,6 +549,8 @@ var mergeDataFrame = exports.mergeDataFrame = function mergeDataFrame(df1, df2,
364549 switch ( how ) {
365550 case 'inner' :
366551 return innerMerge ( df1 , df2 , mergeOn ) ;
552+ case 'outer' :
553+ return outerMerge ( df1 , df2 , mergeOn ) ;
367554 default :
368555 throw new Error ( 'MergeError: ' + how + ' not a supported merge type' ) ;
369556 }
0 commit comments