@@ -1421,7 +1421,7 @@ def _aggregate_multiple_funcs(self, arg):
1421
1421
try :
1422
1422
colg = SeriesGroupBy (obj [col ], column = col ,
1423
1423
grouper = self .grouper )
1424
- results .append (colg .agg (arg ))
1424
+ results .append (colg .aggregate (arg ))
1425
1425
keys .append (col )
1426
1426
except (TypeError , GroupByError ):
1427
1427
pass
@@ -1437,7 +1437,7 @@ def _aggregate_generic(self, func, *args, **kwargs):
1437
1437
obj = self ._obj_with_exclusions
1438
1438
1439
1439
result = {}
1440
- if axis == 0 :
1440
+ if axis != obj . _het_axis :
1441
1441
try :
1442
1442
for name in self .indices :
1443
1443
data = self .get_group (name , obj = obj )
@@ -1453,19 +1453,10 @@ def _aggregate_generic(self, func, *args, **kwargs):
1453
1453
wrapper = lambda x : func (x , * args , ** kwargs )
1454
1454
result [name ] = data .apply (wrapper , axis = axis )
1455
1455
1456
- result_index = self .grouper .levels [0 ]
1457
-
1458
- if result :
1459
- if axis == 0 :
1460
- result = DataFrame (result , index = obj .columns ,
1461
- columns = result_index ).T
1462
- else :
1463
- result = DataFrame (result , index = obj .index ,
1464
- columns = result_index )
1465
- else :
1466
- result = DataFrame (result )
1456
+ return self ._wrap_generic_output (result , obj )
1467
1457
1468
- return result
1458
+ def _wrap_aggregated_output (self , output , names = None ):
1459
+ raise NotImplementedError
1469
1460
1470
1461
def _aggregate_item_by_item (self , func , * args , ** kwargs ):
1471
1462
# only for axis==0
@@ -1477,7 +1468,7 @@ def _aggregate_item_by_item(self, func, *args, **kwargs):
1477
1468
try :
1478
1469
colg = SeriesGroupBy (obj [item ], column = item ,
1479
1470
grouper = self .grouper )
1480
- result [item ] = colg .agg (func , * args , ** kwargs )
1471
+ result [item ] = colg .aggregate (func , * args , ** kwargs )
1481
1472
except (ValueError , TypeError ):
1482
1473
cannot_agg .append (item )
1483
1474
continue
@@ -1488,39 +1479,21 @@ def _aggregate_item_by_item(self, func, *args, **kwargs):
1488
1479
1489
1480
return DataFrame (result , columns = result_columns )
1490
1481
1491
- def _wrap_aggregated_output (self , output , names = None ):
1492
- agg_axis = 0 if self .axis == 1 else 1
1493
- agg_labels = self ._obj_with_exclusions ._get_axis (agg_axis )
1494
-
1495
- if len (output ) == len (agg_labels ):
1496
- output_keys = agg_labels
1482
+ def _decide_output_index (self , output , labels ):
1483
+ if len (output ) == len (labels ):
1484
+ output_keys = labels
1497
1485
else :
1498
1486
output_keys = sorted (output )
1499
1487
try :
1500
1488
output_keys .sort ()
1501
1489
except Exception : # pragma: no cover
1502
1490
pass
1503
1491
1504
- if isinstance (agg_labels , MultiIndex ):
1492
+ if isinstance (labels , MultiIndex ):
1505
1493
output_keys = MultiIndex .from_tuples (output_keys ,
1506
- names = agg_labels .names )
1507
-
1508
- if not self .as_index :
1509
- result = DataFrame (output , columns = output_keys )
1510
- group_levels = self .grouper .get_group_levels ()
1511
- zipped = zip (self .grouper .names , group_levels )
1494
+ names = labels .names )
1512
1495
1513
- for i , (name , labels ) in enumerate (zipped ):
1514
- result .insert (i , name , labels )
1515
- result = result .consolidate ()
1516
- else :
1517
- index = self .grouper .result_index
1518
- result = DataFrame (output , index = index , columns = output_keys )
1519
-
1520
- if self .axis == 1 :
1521
- result = result .T
1522
-
1523
- return result
1496
+ return output_keys
1524
1497
1525
1498
def _wrap_applied_output (self , keys , values , not_indexed_same = False ):
1526
1499
if len (keys ) == 0 :
@@ -1640,13 +1613,51 @@ def __getitem__(self, key):
1640
1613
exclusions = self .exclusions ,
1641
1614
as_index = self .as_index )
1642
1615
1616
+ def _wrap_generic_output (self , result , obj ):
1617
+ result_index = self .grouper .levels [0 ]
1618
+
1619
+ if result :
1620
+ if self .axis == 0 :
1621
+ result = DataFrame (result , index = obj .columns ,
1622
+ columns = result_index ).T
1623
+ else :
1624
+ result = DataFrame (result , index = obj .index ,
1625
+ columns = result_index )
1626
+ else :
1627
+ result = DataFrame (result )
1628
+
1629
+ return result
1630
+
1643
1631
def _get_data_to_aggregate (self ):
1644
1632
obj = self ._obj_with_exclusions
1645
1633
if self .axis == 1 :
1646
1634
return obj .T ._data , 1
1647
1635
else :
1648
1636
return obj ._data , 1
1649
1637
1638
+ def _wrap_aggregated_output (self , output , names = None ):
1639
+ agg_axis = 0 if self .axis == 1 else 1
1640
+ agg_labels = self ._obj_with_exclusions ._get_axis (agg_axis )
1641
+
1642
+ output_keys = self ._decide_output_index (output , agg_labels )
1643
+
1644
+ if not self .as_index :
1645
+ result = DataFrame (output , columns = output_keys )
1646
+ group_levels = self .grouper .get_group_levels ()
1647
+ zipped = zip (self .grouper .names , group_levels )
1648
+
1649
+ for i , (name , labels ) in enumerate (zipped ):
1650
+ result .insert (i , name , labels )
1651
+ result = result .consolidate ()
1652
+ else :
1653
+ index = self .grouper .result_index
1654
+ result = DataFrame (output , index = index , columns = output_keys )
1655
+
1656
+ if self .axis == 1 :
1657
+ result = result .T
1658
+
1659
+ return result
1660
+
1650
1661
def _post_process_cython_aggregate (self , obj ):
1651
1662
# undoing kludge from below
1652
1663
if self .axis == 0 :
@@ -1733,31 +1744,58 @@ def aggregate(self, arg, *args, **kwargs):
1733
1744
1734
1745
return self ._aggregate_generic (arg , * args , ** kwargs )
1735
1746
1736
- def _aggregate_generic (self , func , * args , ** kwargs ):
1737
- result = {}
1747
+ def _wrap_generic_output (self , result , obj ):
1738
1748
1739
- axis = self .axis
1749
+ new_axes = list (obj .axes )
1750
+ new_axes [self .axis ] = self .grouper .result_index
1751
+
1752
+ result = Panel ._from_axes (result , new_axes )
1753
+
1754
+ if self .axis > 0 :
1755
+ result = result .swapaxes (0 , self .axis )
1756
+
1757
+ return result
1740
1758
1759
+ def _aggregate_item_by_item (self , func , * args , ** kwargs ):
1741
1760
obj = self ._obj_with_exclusions
1761
+ result = {}
1762
+ cannot_agg = []
1742
1763
1743
- for name in self .grouper :
1744
- data = self .get_group (name , obj = obj )
1745
- try :
1746
- result [name ] = func (data , * args , ** kwargs )
1747
- except Exception :
1748
- wrapper = lambda x : func (x , * args , ** kwargs )
1749
- result [name ] = data .apply (wrapper , axis = axis )
1764
+ if self .axis > 0 :
1765
+ for item in obj :
1766
+ try :
1767
+ itemg = DataFrameGroupBy (obj [item ],
1768
+ axis = self .axis - 1 ,
1769
+ grouper = self .grouper )
1770
+ result [item ] = itemg .aggregate (func , * args , ** kwargs )
1771
+ except (ValueError , TypeError ):
1772
+ raise
1773
+ # cannot_agg.append(item)
1774
+ # continue
1775
+ new_axes = list (obj .axes )
1776
+ new_axes [self .axis ] = self .grouper .result_index
1777
+ return Panel ._from_axes (result , new_axes )
1778
+ else :
1779
+ raise NotImplementedError
1750
1780
1751
- result = Panel (result )
1781
+ def _wrap_aggregated_output (self , output , names = None ):
1782
+ raise NotImplementedError
1783
+ new_axes = list (self ._obj_with_exclusions .axes )
1784
+ new_axes [self .axis ] = self .grouper .result_index
1752
1785
1753
- if axis > 0 :
1754
- result = result .swapaxes (0 , axis )
1786
+ result = Panel (output , index = self .grouper .result_index ,
1787
+ columns = output_keys )
1788
+
1789
+ if self .axis > 0 :
1790
+ result = result .swapaxes (0 , self .axis )
1755
1791
1756
1792
return result
1757
1793
1794
+
1758
1795
class NDArrayGroupBy (GroupBy ):
1759
1796
pass
1760
1797
1798
+
1761
1799
#----------------------------------------------------------------------
1762
1800
# Grouping generator for BlockManager
1763
1801
0 commit comments