【问题标题】:Definite numerical integration in a python pandas dataframepython pandas数据框中的确定数值积分
【发布时间】:2018-10-19 00:56:00
【问题描述】:

我有一个可变列数的熊猫数据框。我想对数据框的每一列进行数值积分,以便我可以评估从第 0 行到第 'n' 行的定积分。我有一个适用于一维数组的函数,但是有没有更好的方法在 pandas 数据框中执行此操作,这样我就不必遍历列和单元格?我正在考虑使用applymap的某种方式,但我不知道如何使它工作。

这是适用于一维数组的函数:

    def findB(x,y):

        y_int = np.zeros(y.size)
        y_int_min = np.zeros(y.size)
        y_int_max = np.zeros(y.size)
        end = y.size-1

       y_int[0]=(y[1]+y[0])/2*(x[1]-x[0])

       for i in range(1,end,1):
            j=i+1
            y_int[i] = (y[j]+y[i])/2*(x[j]-x[i]) + y_int[i-1]

       return y_int

我想将它替换为一次计算数据帧的多列的东西,如下所示:

    B_df = y_df.applymap(integrator)  

编辑:

起始数据帧 dB_df:

        Sample1 1 dB    Sample1 2 dB    Sample1 3 dB    Sample1 4 dB Sample1 5 dB   Sample1 6 dB
    0   2.472389    6.524537    0.306852    -6.209527   -6.531123   -4.901795
    1   6.982619    -0.534953   -7.537024   8.301643    7.744730    7.962163
    2   -8.038405   -8.888681   6.856490    -0.052084   0.018511    -4.117407
    3   0.040788    5.622489    3.522841    -8.170495   -7.707704   -6.313693
    4   8.512173    1.896649    -8.831261   6.889746    6.960343    8.236696
    5   -6.234313   -9.908385   4.934738    1.595130    3.116842    -2.078000
    6   -1.998620   3.818398    5.444592    -7.503763   -8.727408   -8.117782
    7   7.884663    3.818398    -8.046873   6.223019    4.646397    6.667921
    8   -5.332267   -9.163214   1.993285    2.144201    4.646397    0.000627
    9   -2.783008   2.288842    5.836786    -8.013618   -7.825365   -8.470759

结束数据帧 B_df:

        Sample1 1 B Sample1 2 B Sample1 3 B Sample1 4 B Sample1 5 B Sample1 6 B
    0   0.000038    0.000024    -0.000029   0.000008    0.000005    0.000012
    1   0.000034    -0.000014   -0.000032   0.000041    0.000036    0.000028
    2   0.000002    -0.000027   0.000010    0.000008    0.000005    -0.000014
    3   0.000036    0.000003    -0.000011   0.000003    0.000002    -0.000006
    4   0.000045    -0.000029   -0.000027   0.000037    0.000042    0.000018
    5   0.000012    -0.000053   0.000015    0.000014    0.000020    -0.000023
    6   0.000036    -0.000023   0.000004    0.000009    0.000004    -0.000028
    7   0.000046    -0.000044   -0.000020   0.000042    0.000041    -0.000002
    8   0.000013    -0.000071   0.000011    0.000019    0.000028    -0.000036
    9   0.000000    0.000000    0.000000    0.000000    0.000000    0.000000

在上面的例子中,

    (x[j]-x[i]) = 0.000008

【问题讨论】:

  • 您能否举例说明您的输入 Dataframe 和您的预期输出?
  • 您可能正在寻找apply,但这确实不会比在列上循环更有效。
  • x 来自哪里?是Series、numpy ndarray,还是别的什么?
  • x 来自另一个数组,但对于所有 i 和 j,最终 (x[j]-x[i]) 是一个常数值 0.000008。 @疯狂物理学家
  • x的类型是什么?这比数值重要得多。

标签: python pandas


【解决方案1】:

首先,您可以使用矢量化操作获得类似的结果。积分的每个元素只是当前和下一个y 值的平均值,由x 中的相应差异缩放。最终的积分只是这些元素的累积和。您可以通过执行类似的操作来获得相同的结果

def findB(x, y):
    """
    x : pandas.Series
    y : pandas.DataFrame
    """
    mean_y = (y[:-1] + y.shift(-1)[:-1]) / 2
    delta_x = x.shift(-1)[:-1] - x[:-1]
    scaled_int = mean_y.multiply(delta_x)
    cumulative_int = scaled_int.cumsum(axis='index')
    return cumulative_int.shift(1).fillna(0)

这里DataFrame.shiftSeries.shift 用于将“下一个”元素的索引与当前元素匹配。您必须使用DataFrame.multiply 而不是* 运算符来确保使用正确的轴('index''column')。最后,DataFrame.cumsum 提供了最后的集成步骤。 DataFrame.fillna 确保您有第一行零,就像您在原始解决方案中所做的那样。使用所有原生 pandas 函数的优势在于,您可以传入具有任意数量列的数据框,并让它同时对所有列进行操作。

【讨论】:

    【解决方案2】:

    您真的在寻找积分的数值吗?也许您只需要一张图片?那么使用 pyplot 会更容易。

    import matplotlib.pyplot as plt
    # Introduce a column *bin* holding left limits of our bins.
    df['bin'] = pd.cut(df['volume2'], 50).apply(lambda bin: bin.left)
    # Group by bins and calculate *f*.
    g = df[['bin', 'universe']].groupby('bin').sum()
    # Plot the function using cumulative=True.
    plt.hist(list(g.index), bins=50, weights=list(g['universe']), cumulative=True)
    plt.show()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-05
      • 1970-01-01
      • 2018-10-14
      • 2017-06-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多