将涉及 pandas 中另一个数据帧的用户定义函数应用于整个数据帧

apply to the entire dataframe a user-defined function involving another dataframe in pandas

我正在尝试在两个数据帧 df1 和 df2 之间做一些数学运算,但我发现很难使用 pd.apply 函数:

df1:

   number1  number2  number3  … 
0   0         0        0      …
1   0         0.25     0      …
2   0.1       0.1      0      …
3   0         0        0.3    …
4   0         0        0      … 

df2:

   number1  number2  number3    … 
0   2         3.3        6      …
1   2.1       3.4        6      …
2   2.2       3.2      5.8      …
3   2.1       3.4      6.2      …
4   2         4.0      6.4      … 

我想按照以下规则更改 df1 中的每个元素:

  1. 将 df1 中的每 0 个元素更改为 1
  2. df1中的每个非零元素,让df.iloc[m,n] = (1-df.iloc[m,n])/df2.shift(1).iloc [m,n],其中m,n为非零元素的位置

现在我有了一个有效的代码:

df1_new=pd.DataFrame(1,index = df1.index,columns = df1.columns)
df2_sft=df2.shift(1)
m,n=np.where(np.array(df1)!=0)
for i in m:
  for j in n:
    df1_new.iloc[i,j]=(1-df1.iloc[i,j])/df2_sft.iloc[i,j]

但是如您所见,如果 df1 和 df2 很大,它就会变得丑陋且非常慢。我相信一定有很多其他的方法可以很快地完成这个简单的数学运算,希望你能给予一些帮助。

此外,我总是对 apply 和 applymap 感到困惑,有什么区别,什么时候应该使用一个而不是另一个?

你想对你的代码进行矢量化,也就是说,而不是使用 for 循环进行整体计算 DataFrame/array,像下面这样的事情会快得多:

In [11]: ((1 - df1) / df2_sft).where(df1 != 0, 1)
Out[11]:
    number1   number2  number3
0  1.000000  1.000000  1.00000
1  1.000000  0.227273  1.00000
2  0.428571  0.264706  1.00000
3  1.000000  1.000000  0.12069
4  1.000000  1.000000  1.00000

注意:这与您的代码不匹配(不正确)不要仅遍历非零元素(当您遍历n 中每个元素的 m 中的所有项目,而不是压缩项目)。