大熊猫数据帧的选择性划分

时间:2016-02-04 04:00:34

标签: python pandas dataframe

假设我有两个Pandas数据帧,一个带负数,一个带正数,看起来像这样:

Columns 1  2  3            Columns 1  2  3
Rows                       Rows
1      -4 -6 -5            1       9  3  2
2      -2 -8 -4            2       6  4  5
3      -8 -8 -3            3       8  2  5

然后我有另一个具有相同尺寸的Pandas数据帧,但是具有负数和正数,如下所示:

Columns 1  2  3
Rows
1      -2  3 -4
2      -1 -2  2
3       6 -8  3

对于此混合数据帧中的每个元素,如果值为负,我想将其除以负数据帧中的相应元素,如果值为正,我想将其除以正数中的相应元素数据帧。结果如下:

Columns  1     2    3
Rows
1      0.5   1.0  0.8
2      0.5  0.25  0.4
3     0.75   1.0  0.6

执行此操作的最佳pythonic和/或有效方法是什么?我将拥有10,000个混合数据帧,包含50行和105列。

2 个答案:

答案 0 :(得分:1)

我不了解效率,但您可以使用where非常干净地完成这项工作:

>>> df1
   0  1  2
0  3  8  7
1  9  9  3
2  1  1  9
>>> df2
   0  1  2
0 -3 -7 -8
1 -4 -6 -3
2 -8 -8 -3
>>> df3
    0  1  2
0 -10  7  1
1 -10 -4  9
2   7 -8  0
>>> df3/df1.where(df3 >= 0, df2)
          0         1         2
0  3.333333  0.875000  0.142857
1  2.500000  0.666667  3.000000
2  7.000000  1.000000  0.000000

答案 1 :(得分:1)

这是一种替代方法,看起来更快。它基本上在混合数据帧上创建一个布尔掩码,然后将其除以适当的正或负数据帧。因为正面和负面是相互排斥的,所以可以将结果相加以产生分母。然后将其乘以混合数据帧以获得所需结果。

根据您的原始数据:

>>> df3 * (df3.gt(0) / df2 + df3.lt(0) / df1)
      0     1    2
0  0.50  1.00  0.8
1  0.50  0.25  0.4
2  0.75  1.00  0.6

使用更大的10kx10k DataFrame:

df_pos = pd.DataFrame(np.random.randn(10000, 10000)).abs()
df_neg = -pd.DataFrame(np.random.randn(10000, 10000)).abs()
df_mixed = pd.DataFrame(np.random.randn(10000, 10000))

与@DSM解决方案的时间比较可以说更简单:

%timeit -n 10 df_mixed * (df_mixed.ge(0) / df_pos + df_mixed.lt(0) / df_neg)
10 loops, best of 3: 1.45 s per loop

%timeit -n 10 df_mixed / df_pos.where(df_mixed >= 0, df_neg)
10 loops, best of 3: 6.5 s per loop