pandas数据框中列的条件数学运算

92dk7w1h  于 2023-06-20  发布在  其他
关注(0)|答案(1)|浏览(115)

我在dataframe中有一堆具有不同值的列,如以下示例所示:

Especies  Especies_0  Especies_1  Especies_2  Especies_3
2.20        3.44        1.90        1.24        0.00
2.20        3.04        2.55        0.00        0.00
1.88        2.19        0.00        0.00        0.00
2.20        3.44        2.28        2.55        0.00
3.44        2.20        0.00        0.00        0.00
2.20        2.58        0.00        0.00        0.00
1.88        2.19        0.00        0.00        0.00
3.44        1.91        3.04        1.83        3.98
3.44        2.20        0.00        0.00        0.00
2.20        2.55        1.90        0.00        0.00
1.88        2.20        0.00        0.00        0.00

我要执行的操作是:
avg(abs(max - col) for col in cols)
其中max是每行中的列的最大值(例如,对于第一行,max将是3.44,cols是列中的其余值),abs是绝对函数,avg表示取平均值。
例如,对于第一行,操作将是:((3.44-2.20)+(3.44-1.90)+(3.44-1.24))/3 = 1.66
对于第5行,值为(3.44, 2.20, 0.00, 0.00, 0.00),结果将是:(3.44 -2.20) /1 = 1.24
这很简单,但是有一个问题,我不想考虑最大值的列,或者任何包含0.0的列(考虑到最大值列的变化,它并不总是与包含0.0的列的数量相同)。
我已经成功地用单个标量值来实现了,我甚至做了一个函数来实现这一点

def ele_diff(esp0, esp1, esp2, esp3, esp4):
    species = sorted([esp0, esp1, esp2, esp3, esp4])
    diff = [species[-1] - spec for spec in species if spec != 0.0 and spec !=species[-1]]
    return (sum(diff)/len(diff))

但是我不能把我的函数应用到 Dataframe 上。我试过df.apply()df.applymap(),但它们似乎不适用于我所做的函数(applymap只考虑1个输入和1个输出,而apply并没有分别为函数提供每一行,因此函数返回ValueError,因为序列的真值是不明确的)。
我也试过直接用dataframe来做,但由于它有复杂的逻辑,我还没能找到解决方案。
我遇到的主要问题似乎是检查我要减去的值是否不是0.0或最大值。

zu0ti5jz

zu0ti5jz1#

首先通过在DataFrame.filter中启动子字符串Especies来过滤必要的列,为最大值和0值设置缺失值,减去最大值,转换为绝对值,最后得到平均值:

df1 = df.filter(regex='^Especies')

#or if necessary specify columns names in list
#cols = ['Especies', 'Especies_0', 'Especies_1', 'Especies_2', 'Especies_3']
#df1 = df[cols]

max1 = df1.max(axis=1)
mask = df1.ne(max1, axis=0) & df1.ne(0)
df['new'] = df1.where(mask).sub(max1, axis=0).abs().mean(axis=1)
print (df)
    Especies  Especies_0  Especies_1  Especies_2  Especies_3       new
0       2.20        3.44        1.90        1.24        0.00  1.660000
1       2.20        3.04        2.55        0.00        0.00  0.665000
2       1.88        2.19        0.00        0.00        0.00  0.310000
3       2.20        3.44        2.28        2.55        0.00  1.096667
4       3.44        2.20        0.00        0.00        0.00  1.240000
5       2.20        2.58        0.00        0.00        0.00  0.380000
6       1.88        2.19        0.00        0.00        0.00  0.310000
7       3.44        1.91        3.04        1.83        3.98  1.425000
8       3.44        2.20        0.00        0.00        0.00  1.240000
9       2.20        2.55        1.90        0.00        0.00  0.500000
10      1.88        2.20        0.00        0.00        0.00  0.320000

详情

print (df1.where(mask))
    Especies  Especies_0  Especies_1  Especies_2  Especies_3
0       2.20         NaN        1.90        1.24         NaN
1       2.20         NaN        2.55         NaN         NaN
2       1.88         NaN         NaN         NaN         NaN
3       2.20         NaN        2.28        2.55         NaN
4        NaN        2.20         NaN         NaN         NaN
5       2.20         NaN         NaN         NaN         NaN
6       1.88         NaN         NaN         NaN         NaN
7       3.44        1.91        3.04        1.83         NaN
8        NaN        2.20         NaN         NaN         NaN
9       2.20         NaN        1.90         NaN         NaN
10      1.88         NaN         NaN         NaN         NaN
print (df1.where(mask).sub(max1, axis=0))
    Especies  Especies_0  Especies_1  Especies_2  Especies_3
0      -1.24         NaN       -1.54       -2.20         NaN
1      -0.84         NaN       -0.49         NaN         NaN
2      -0.31         NaN         NaN         NaN         NaN
3      -1.24         NaN       -1.16       -0.89         NaN
4        NaN       -1.24         NaN         NaN         NaN
5      -0.38         NaN         NaN         NaN         NaN
6      -0.31         NaN         NaN         NaN         NaN
7      -0.54       -2.07       -0.94       -2.15         NaN
8        NaN       -1.24         NaN         NaN         NaN
9      -0.35         NaN       -0.65         NaN         NaN
10     -0.32         NaN         NaN         NaN         NaN

相关问题