将DataFrame的每n个索引乘以(或除以)数组中的常量

时间:2019-03-22 17:07:00

标签: python pandas dataframe

我有一个DataFrame,我想将每n个索引乘以(或除以)数组中的特定数字。下面是一个简单的示例,其中字母只是数字。

df =

   0  1
0  A  B
1  C  D
2  E  F
3  G  H
4  I  J
5  K  L
6  M  N
7  O  P

DataFrame(或numpy数组):

   0  1
0  W  X
1  Y  Z

我想获得以下结果:

结果=

   0     1
0  A/W  B/X
1  C/Y  D/Z
2  E/W  F/X
3  G/Y  H/Z
4  I/W  J/X
5  K/Y  L/Z
6  M/W  N/X
7  O/Y  P/Z

是否可以使用df.groupy(df % 2).agg()df.groupy(df % 2).apply()解决此问题?我正在处理一个巨大的DataFrame,我相信如果应用for循环将花费比所需更多的时间。

我知道我必须使用一个函数,但是我不能编写一个能满足我需求的函数。

谢谢。

3 个答案:

答案 0 :(得分:1)

尝试以下代码:

从定义要应用于每个组的功能开始:

def dv(tbl):
    return tbl.divide(df2.values, axis='columns')

df2转换为基础values以便“免费” 从索引对齐中退出。

然后我们读取 df2 中的行数(组的大小 在 df 分组中):

len2 = len(df2.index)

然后可以用一条指令执行实际的除法运算:

df.groupby(np.arange(len(df.index)) // len2).apply(dv)

np.arange(len(df.index)) // len2df分为 组包含与df2相同的行数。

对每个组应用dv函数(如上定义)。

出于测试目的,我创建了第一个DataFrame( df ):

      0     1
0  10.0  11.0
1  12.0  13.0
2  14.0  15.0
3  16.0  17.0
4  18.0  19.0
5  20.0  21.0
6  22.0  23.0
7  24.0  25.0

和第二个( df2 )为:

     0    1
0  2.0  2.5
1  3.0  3.5

结果是:

           0         1
0   5.000000  4.400000
1   4.000000  3.714286
2   7.000000  6.000000
3   5.333333  4.857143
4   9.000000  7.600000
5   6.666667  6.000000
6  11.000000  9.200000
7   8.000000  7.142857

当然,上面的代码是用于除法的。

如果要相乘,请定义一个函数:

def ml(tbl):
    return tbl.multiply(df2.values, axis='columns')

并调用它:

df.groupby(np.arange(len(df.index)) // len2).apply(ml)

答案 1 :(得分:0)

这应该可以解决问题,而无需循环或使用Apply:

df.iloc[::2, 0] = df.iloc[::2, 0] / df2.iloc[0, 0]
df.iloc[1::2, 0] = df.iloc[1::2, 0] / df2.iloc[0, 1]
df.iloc[::2, 1] = df.iloc[::2, 1] / df2.iloc[1, 0]
df.iloc[1::2, 1] = df.iloc[1::2, 1] / df2.iloc[1, 1]

这可能也可以使用,并且可以用于任意数量的列:

df.iloc[::2, :] = df.iloc[::2, :] / df2.iloc[0, :]
df.iloc[1::2, :] = df.iloc[1::2, :] / df2.iloc[1, :]

答案 2 :(得分:0)

您可以如下修改第一个数据框的索引:

df.index = df.index % 2

然后在索引上合并:

df = df.join(df2, lsuffix='_l', rsuffix = '_r')

然后您想要的将是这样

df['ratio1'] = df['0_l'] / df['0_r']
df['ratio2'] = df['1_l'] / df['1_r']

要获得确切答案的形式:

column_map = {'ratio1': 0, 'ratio2': 1}
df = df[['ratio1', 'ratio2']].rename(columns= column_map)