对 DataFrame 中的元素进行成对计算
Pairwise calculation on elements in a DataFrame
我有一个结构类似于以下的数据框(但在实际情况下有更多的行和列)。
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
其中每个元素是原始数据框对应元素的商。
我一直想不出如何方便地做到这一点。
为了方便起见,最好不要只提供 "before" 和 "after" 值的第一列和最后一列的名称,即 '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 进行一些操作以更直接的方式实现这一点。
是否没有直接在 DataFrame 上进行元素计算而不是通过 numpy 数组的操作?
您始终可以使用 df.filter
到 select 相关的列名。它可以接受正则表达式,因此您可以使用如下内容指定 after/before 列:
>>> 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 数组没有标记索引,因此元素操作成功。
我有一个结构类似于以下的数据框(但在实际情况下有更多的行和列)。
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
其中每个元素是原始数据框对应元素的商。
我一直想不出如何方便地做到这一点。
为了方便起见,最好不要只提供 "before" 和 "after" 值的第一列和最后一列的名称,即 '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
.
这个方法我从这个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 进行一些操作以更直接的方式实现这一点。
是否没有直接在 DataFrame 上进行元素计算而不是通过 numpy 数组的操作?
您始终可以使用 df.filter
到 select 相关的列名。它可以接受正则表达式,因此您可以使用如下内容指定 after/before 列:
>>> 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 数组没有标记索引,因此元素操作成功。