首页 > 解决方案 > 使用函数创建数据框列

问题描述

我有一个名为的数据框df,如下所示:

            dept          ratio higher  lower
      date  
01/01/1979     B    0.522576565      2      1
01/01/1979     A    0.940614079      2      2
01/01/1979     C    0.873957946      0      1
01/01/1979     B    0.087828824      0      2
01/01/1979     A    0.39754345       1      2
01/01/1979     A    0.475491609      1      2
01/01/1979     B    0.140605283      0      2
01/01/1979     A    0.071007362      0      2
01/01/1979     B    0.480720923      2      2
01/01/1979     A    0.673142643      1      2
01/01/1979     C    0.73554271       0      0

我想compared为每一行创建一个名为 where 的新列,我想计算dept列中与行dept值减 1 匹配的值的数量。如果计数大于或等于 1,那么我想返回该compared列解决以下问题:

`compared` row value = (higher - lower) / count of dept column which matches the dept row value - 1

如果部门数为 0,则比较列将返回 0。

例如,对于值中的第一行,dfB deptdept列中有 4 个 B 值。4-1 大于 1。因此,在新compared列中,我想输入higher列值 (2) 减去lower列值 (1),等于 1 除以 4-1

或者

(2-1)/(4-1) = 0.333333333

所以我想要的输出看起来像:

            dept          ratio higher  lower      compared
date    
01/01/1979     B    0.522576565      2      1   0.333333333
01/01/1979     A    0.940614079      2      2   0.000000000
01/01/1979     C    0.873957946      0      1  -1.000000000
01/01/1979     B    0.087828824      0      2  -0.666666667
01/01/1979     A    0.39754345       1      2  -0.250000000
01/01/1979     A    0.475491609      1      2  -0.250000000
01/01/1979     B    0.140605283      0      2  -0.666666667
01/01/1979     A    0.071007362      0      2  -0.500000000
01/01/1979     B    0.480720923      2      2   0.000000000
01/01/1979     A    0.673142643      1      2  -0.250000000
01/01/1979     C    0.73554271       0      0   0.000000000

我有一些代码,但它真的很慢:

    minDept=1
    for staticidx, row in df.iterrows():
        dept = row['dept']
        deptCount = deptPivot.loc[dept, "date"] # if error then zero
        myLongs= df.loc[staticidx, "higher"]
        myShorts= df.loc[staticidx, "lower"]

        if deptCount > minDept:

           df.loc[staticidx, "compared"] = (higher- lower)/(deptCount-1)

        else:
           df.loc[staticidx, "compared"] = 0

有没有更快的方法可以做到这一点?

标签: pythonpandas

解决方案


这很简单:

counts = df.groupby('dept')['dept'].transform('count')-1

df['compared'] = (df['higher']-df['lower'])/counts

# to avoid possible division by zero warning
# also to match `counts>0` condition
# use this instead
# df.loc[counts>0,'compared'] = df['higher'].sub(df['lower']).loc[counts>0]/counts[counts>0]

输出:

           dept     ratio  higher  lower  compared
date                                              
01/01/1979    B  0.522577       2      1  0.333333
01/01/1979    A  0.940614       2      2  0.000000
01/01/1979    C  0.873958       0      1 -1.000000
01/01/1979    B  0.087829       0      2 -0.666667
01/01/1979    A  0.397543       1      2 -0.250000
01/01/1979    A  0.475492       1      2 -0.250000
01/01/1979    B  0.140605       0      2 -0.666667
01/01/1979    A  0.071007       0      2 -0.500000
01/01/1979    B  0.480721       2      2  0.000000
01/01/1979    A  0.673143       1      2 -0.250000
01/01/1979    C  0.735543       0      0  0.000000

推荐阅读