如何将熊猫数据框值除以每组的第一行?

Posted

技术标签:

【中文标题】如何将熊猫数据框值除以每组的第一行?【英文标题】: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

谢谢,

【问题讨论】:

【参考方案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' >>> 谢谢。但不是现阶段升级熊猫的可行方案。我需要想办法。

以上是关于如何将熊猫数据框值除以每组的第一行?的主要内容,如果未能解决你的问题,请参考以下文章

如何计算熊猫数据框中每组的行数并将其添加到原始数据中

从熊猫数据框中选择排序组的第一行

如何选择每组的第一行?

如何获得每组的第一行?

如何根据多个排序列选择每组的第一行?

只用 pandas 获取每组的第一行和最后一行