将带参数的函数应用于dataFram

2024-07-02 12:48:37 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图将一个函数应用于数据帧,其中参数来自数据帧本身。有什么方法可以简洁地做到这一点吗?你知道吗

df: 
    | a  | b  | c  | d |
A   | 20 | 15 | 33 | 5 |
B   | 5  | 6  | 10 | 8 |
C   | 10 | 15 | 5  | 10|

应用于每个单元格的函数

# c = sum of the current column
# r = sum of the current row 
# t = sum of all values
def calcIndex(x, c, r, t):
    return (x/c)*(t/r)*100

结果

    | a   | b   | c   | d   |
A   | 111 | 81  | 134 | 42  |
B   | 70  | 82  | 102 | 170 |
C   | 101 | 148 | 37  | 154 |

我试过df.apply,但不确定如何访问特定的行/列总数,具体取决于计算的x


Tags: ofthe数据方法函数df参数def
2条回答

这个问题有点棘手。你知道吗

data = pd.DataFrame({'a':[20, 5, 10], 'b':[15, 6, 15], 'c':[33, 10, 5], 'd':[5, 8, 10]}, index=['A', 'B', 'C'])

total = data.values.sum() # total sum

data['row_sum'] = data.sum(axis=1) # create a new column 'row_sum' containing sum of elements in that row
col_sum = data.sum(axis=0) # column sum

data = data.loc[:,'a':'d'].div(data['row_sum'], axis=0) # divide each cell with its row sum
data.loc['col_sum'] = col_sum # create a new row with corresponding column sum
data = data.loc['A':'C',:].div(data.loc['col_sum'], axis=1) # divide each cell with its column sum

def update(x):
    return int(round(x*total*100)) # round number to nearest integer       

data_new = data.applymap(update)

输出:

     a    b    c    d
A  111   81  134   42
B   70   82  102  170
C  101  148   37  154

这里的^{}问题可能是按列或按索引循环,而不是按二者循环,因此不能在这里使用,如果需要在一个函数中同时使用二者。你知道吗

更好更快的方法是将向量化函数与^{}^{}^{}一起使用,最后将^{}^{}一起用于输出中的整数:

c = df.sum(axis=1)
r = df.sum()
t = r.sum()
df1 = df.div(c, axis=0).mul(t).div(r).mul(100).round().astype(int)
print (df1)
     a    b    c    d
A  111   81  134   42
B   70   82  102  170
C  101  148   37  154

为了提高性能,可以使用numpy

#pandas 0.24+
arr = df.to_numpy()
#pandas below
#arr = df.values
c = arr.sum(axis=1)
r = arr.sum(axis=0)
t = r.sum()
out = np.round(arr / c[:, None] * t / r * 100).astype(int)
df = pd.DataFrame(out, index=df.index, columns=df.columns)
print (df)
     a    b    c    d
A  111   81  134   42
B   70   82  102  170
C  101  148   37  154

相关问题 更多 >