【问题标题】:How to divide pandas dataframe's value by its first row by each group?如何将熊猫数据框值除以每组的第一行?
【发布时间】:2017-04-05 13:47:10
【问题描述】:

熊猫数据框:

>>> df
                  sales  net_pft
STK_ID RPT_Date                 
002138 20140930   3.325    0.607
       20150930   3.619    0.738
       20160930   4.779    0.948
600004 20140930  13.986    2.205
       20150930  14.226    3.080
       20160930  15.499    3.619
600660 20140930  31.773    5.286
       20150930  31.040    6.333
       20160930  40.062    7.186

只想知道如何获得输出,因为每一行的值除以每组的第一行,如下所示:

                  sales  net_pft
STK_ID RPT_Date                 
002138 20140930   1.000    1.000
       20150930   1.088    1.216
       20160930   1.437    1.562
600004 20140930   1.000    1.000
       20150930   1.017    1.397
       20160930   1.108    1.641
600660 20140930   1.000    1.000
       20150930   0.977    1.198
       20160930   1.261    1.359

谢谢,

【问题讨论】:

    标签: python pandas normalization


    【解决方案1】:
    import pandas as pd
    
    df = pd.DataFrame({'RPT_Date': ['20140930', '20150930', '20160930', '20140930', '20150930', '20160930', '20140930', '20150930', '20160930'], 'STK_ID': ['002138', '002138', '002138', '600004', '600004', '600004', '600660', '600660', '600660'], 'net_pft': [0.607, 0.738, 0.948, 2.205, 3.080, 3.619, 5.286, 6.333, 7.186], 'sales': [3.325, 3.619, 4.779, 13.986, 14.226, 15.499, 31.773, 31.040, 40.062]})
    df = df.set_index(['STK_ID','RPT_Date'])
    
    firsts = (df.groupby(level=['STK_ID']).transform('first'))
    result = df / firsts
    

    产量

                      net_pft     sales
    STK_ID RPT_Date                    
    002138 20140930  1.000000  1.000000
           20150930  1.215815  1.088421
           20160930  1.561779  1.437293
    600004 20140930  1.000000  1.000000
           20150930  1.396825  1.017160
           20160930  1.641270  1.108180
    600660 20140930  1.000000  1.000000
           20150930  1.198070  0.976930
           20160930  1.359440  1.260882
    

    上面的主要技巧是使用groupby/transform('first')创建一个DataFrame 它的形状与df 相同,但其值来自每个组的第一行:

    firsts = df.groupby(level=['STK_ID']).transform('first')
    #                  net_pft   sales
    # STK_ID RPT_Date                 
    # 002138 20140930    0.607   3.325
    #        20150930    0.607   3.325
    #        20160930    0.607   3.325
    # 600004 20140930    2.205  13.986
    #        20150930    2.205  13.986
    #        20160930    2.205  13.986
    # 600660 20140930    5.286  31.773
    #        20150930    5.286  31.773
    #        20160930    5.286  31.773
    

    虽然这是对内存的过度使用,但这可能是获得所需结果的最快方法,因为它避免了循环遍历 Python 中的组。


    如果上述代码在 Pandas 0.13 版中引发TypeError: Transform function invalid for data types,您可以尝试使用以下解决方法:

    result = list()
    for key, grp in df.groupby(level=['STK_ID']):
        result.append(grp/grp.iloc[0])
    result = pd.concat(result)
    print(result)
    

    【讨论】:

    • 我使用pandas 13.0,遇到如下问题:>>> first = df.groupby(level=['STK_ID']).transform('first') Traceback (last last call last): File “”,第 1 行,在 文件中“C:\Anaconda\lib\site-packages\pandas\core\groupby.py”,第 2319 行,在 transform return self._transform_item_by_item(obj, fast_path) 文件中“C:\Anaconda\lib\site-packages\pandas\core\groupby.py”,第 2386 行,在 _transform_item_by_item 中引发 TypeError('Transform function invalid for data types') TypeError: Transform function invalid for data types
    • df 中的列的 dtype 是什么?请发帖df.info()
    • >>> df.info() MultiIndex: 9 个条目,(002138, 20140930) 到 (600660, 20160930) 数据列(共 2 列): sales 9 non-null float64 net_pft 9 non-null float64 dtypes: float64(2)>>>
    • >>> pd.__version__ '0.13.1' >>>
    • 谢谢。但不是现阶段升级熊猫的可行方案。我需要想办法。
    猜你喜欢
    • 2013-12-02
    • 1970-01-01
    • 2018-02-28
    • 1970-01-01
    • 2022-08-04
    • 1970-01-01
    相关资源
    最近更新 更多