【问题标题】:Pairwise calculation on elements in a DataFrameDataFrame中元素的成对计算
【发布时间】:2015-01-10 18:55:23
【问题描述】:

我有一个类似于以下结构的数据框(但在实际情况下有更多的行和列)。

In [2]: Ex   # The example DataFrame
Out[2]: 
       NameBef  v1B  v2B   v3B   v4B    NameAft  v1A  v2A   v3A   v4A
Id                                                                   
422   firstBef  133  145   534   745   FirstAft  212  543  2342  4563
862  secondBef  234  434   345  3453  SecondAft  643  493  3433   234
935   thirdBef  232  343  6454   463   thirdAft  423  753   754   743

对于每一行,我想从上面计算每个 vXB 和 vXA 值的商(X 是变量),最终得到一个像这样的 DataFrame

          v1Q       v2Q       v3Q       v4Q
Id                                         
422  1.593985  3.744828  4.385768  6.124832
862  2.747863  1.135945  9.950725  0.067767
935  1.823276  2.195335  0.116827  1.604752

其中每个元素是原始数据框对应元素的商。

我还没有弄清楚如何方便地做到这一点。

为方便起见,最好不要只提供“之前”和“之后”值的第一列和最后一列的名称,即“v1B”、“v4B”和“v1A”, 'v4A'(即不是每一列)。

以下是我想出的。

In [3]: C=Ex.columns
In [4]: C1B=C.get_loc('v1B')
In [5]: C2B=C.get_loc('v4B')
In [6]: C1A=C.get_loc('v1A')
In [7]: C2A=C.get_loc('v4A')
In [8]: FB=Ex.ix[:,C1B:C2B+1]
In [9]: FA=Ex.ix[:,C1A:C2A+1]

In [10]: FB           # The FB and FA frames have this structure
Out[10]: 
     v1B  v2B   v3B   v4B
Id                       
422  133  145   534   745
862  234  434   345  3453
935  232  343  6454   463

[3 rows x 4 columns]

然后最终生成所需的DataFrame。这是通过对 DataFrame.values 生成的 numpy 数组进行计算来完成的。

这个方法我从这个question/answer得到的:

In [12]: DataFrame((FA.values*1.0) / FB.values,columns=['v1Q','v2Q','v3Q','v4Q'],index=Ex.index)
Out[12]: 
          v1Q       v2Q       v3Q       v4Q
Id                                         
422  1.593985  3.744828  4.385768  6.124832
862  2.747863  1.135945  9.950725  0.067767
935  1.823276  2.195335  0.116827  1.604752

[3 rows x 4 columns]

我错过了什么吗?我希望通过对原始 DataFrame 进行一些操作,以更直接的方式实现这一点。

是否没有直接在 DataFrames 上进行元素计算而不是通过 numpy 数组进行的操作?

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    您始终可以使用df.filter 来选择相关的列名。它可以接受正则表达式,因此您可以使用以下内容指定后/前列:

    >>> df.filter(regex=r'^v.A$').values / df.filter(regex=r'^v.B$').values
    array([[ 1.59398496,  3.74482759,  4.38576779,  6.12483221],
           [ 2.74786325,  1.1359447 ,  9.95072464,  0.06776716],
           [ 1.82327586,  2.19533528,  0.11682677,  1.60475162]])
    

    关于算术运算,您不会遗漏任何东西。这里有必要使用 Numpy 数组 (.values),否则 Pandas 会根据两个 DataFrame 中的公共索引标签计算值。如果缺少索引,则计算结果为NaN。 Numpy 数组没有标记索引,因此元素操作成功。

    【讨论】:

    • 哇,这肯定更紧凑。摆脱所有这些手动列提取。我只需要选择易于按照您描述的方式过滤掉的列名。也感谢您确认做 numpy 的事情是正确的。
    • 没问题,很高兴听到filter 可能会有所帮助。
    猜你喜欢
    • 2020-02-04
    • 2018-07-04
    • 2021-12-09
    • 1970-01-01
    • 2021-02-11
    • 2011-02-04
    • 2022-01-02
    • 2015-12-26
    • 2021-08-18
    相关资源
    最近更新 更多