在 Pandas 中学习使用地图
Learning to use map in Pandas
我想为两个数据框列 df1 和 df2 逐行建模此 excel 公式:
=IF(df1 > df2; df2; df2 - df1)
我知道这可以通过 Python 中的 map 来完成,但不知道如何实现。我可以使用 for 循环和 if-else 语句来完成它,但这会使我的代码更难阅读。
你能帮帮我吗?
这实际上是 mask
或 where
的工作。
df2.mask(df1 <= df2, df2 - df1)
或者,
df2.where(df1 > df2, df2 - df1)
更一般地说,这是来自 numpy:
np.where(df1 > df2, df2, df2 - df1)
对于这些示例数据帧:
df1
Out:
A B C
0 0.446762 -0.435975 0.109038
1 -0.729108 3.670354 0.761667
2 -0.244370 -0.256956 -1.831161
df2
Out:
A B C
0 -1.192108 0.074628 -0.087634
1 -0.324098 0.698479 -0.287896
2 1.807863 -2.564992 -2.361296
前两个收益率
A B C
0 -1.192108 0.510603 -0.087634
1 0.405010 0.698479 -0.287896
2 2.052233 -2.564992 -2.361296
np.where
returns 一个 numpy 数组,因此您可能需要将其转换回 DataFrame:
array([[-1.19210755, 0.51060284, -0.08763422],
[ 0.40500973, 0.69847936, -0.28789618],
[ 2.05223294, -2.56499239, -2.36129577]])
我想你的意思是创建一个新列,它是列 df1
和 df2
的函数,按照你描述的方式。 (如果我错了,请纠正我。)
那么这是一个使用apply
函数的案例,使用pandas你应该熟悉一下。假设您的数据框称为 df
,您的新列将称为 df3
。那么:
df3 = df.apply(lambda x : x["df2"] if x["df1"] > x["df2"] else x["df2"] - x["df1"], axis=1)
这里发生了很多事情,特别是因为你是 applying to the whole DataFrame
(usually you see apply
used with just one column as input - technically, apply
to a Series
- 而且语法更简单。)需要 axis=1
向 pandas 解释这应该应用于列集(您可能认为这是默认设置,但事实并非如此,因此在应用于整个 DataFrame
时请始终记住使用它。)lambda
用于访问两列并执行功能;在这里,x
是抽象的 DataFrame
本身的任何行。基本上,这是一种进行矢量化映射的方法。它是 pandas 中最常用的工具之一,您会发现自己经常使用它。
一个很好的基础 apply
教程是 here, showing mostly applications to a single column (with the simpler syntax I mentioned, where you don't need axis=1
.) Here also 是另一个应用于多列的示例。
这可以通过
实现
df2 - df1*(df2 > df1)
例如,
In [51]: df1
Out[51]:
0 0.588922
1 0.876270
2 0.276917
3 0.521514
dtype: float64
In [52]: df2
Out[52]:
0 0.628234
1 0.492461
2 0.782199
3 0.759758
dtype: float64
In [53]: df2 - df1*(df2 > df1)
Out[53]:
0 0.039312
1 0.492461
2 0.505282
3 0.238245
dtype: float64
在性能方面,目前发布的三个解决方案在 (100000, 2) 形 DataFrame 上的表现如下:
In [124]: df = pd.DataFrame()
In [125]: df['df1'] = np.random.uniform(size=10**5)
In [126]: df['df2'] = np.random.uniform(size=10**5)
In [127]: df1 = df.df1
In [128]: df2 = df.df2
In [130]: %timeit df.apply(lambda x : x["df2"] if x["df1"] > x["df2"] else x["df2"] - x["df1"], axis=1)
1 loop, best of 3: 8.97 s per loop
In [131]: %timeit df2.where(df1 > df2, df2 - df1)
100 loops, best of 3: 3.57 ms per loop
In [132]: %timeit df2 - df1*(df2 > df1)
1000 loops, best of 3: 1.61 ms per loop
我想为两个数据框列 df1 和 df2 逐行建模此 excel 公式:
=IF(df1 > df2; df2; df2 - df1)
我知道这可以通过 Python 中的 map 来完成,但不知道如何实现。我可以使用 for 循环和 if-else 语句来完成它,但这会使我的代码更难阅读。
你能帮帮我吗?
这实际上是 mask
或 where
的工作。
df2.mask(df1 <= df2, df2 - df1)
或者,
df2.where(df1 > df2, df2 - df1)
更一般地说,这是来自 numpy:
np.where(df1 > df2, df2, df2 - df1)
对于这些示例数据帧:
df1
Out:
A B C
0 0.446762 -0.435975 0.109038
1 -0.729108 3.670354 0.761667
2 -0.244370 -0.256956 -1.831161
df2
Out:
A B C
0 -1.192108 0.074628 -0.087634
1 -0.324098 0.698479 -0.287896
2 1.807863 -2.564992 -2.361296
前两个收益率
A B C
0 -1.192108 0.510603 -0.087634
1 0.405010 0.698479 -0.287896
2 2.052233 -2.564992 -2.361296
np.where
returns 一个 numpy 数组,因此您可能需要将其转换回 DataFrame:
array([[-1.19210755, 0.51060284, -0.08763422],
[ 0.40500973, 0.69847936, -0.28789618],
[ 2.05223294, -2.56499239, -2.36129577]])
我想你的意思是创建一个新列,它是列 df1
和 df2
的函数,按照你描述的方式。 (如果我错了,请纠正我。)
那么这是一个使用apply
函数的案例,使用pandas你应该熟悉一下。假设您的数据框称为 df
,您的新列将称为 df3
。那么:
df3 = df.apply(lambda x : x["df2"] if x["df1"] > x["df2"] else x["df2"] - x["df1"], axis=1)
这里发生了很多事情,特别是因为你是 applying to the whole DataFrame
(usually you see apply
used with just one column as input - technically, apply
to a Series
- 而且语法更简单。)需要 axis=1
向 pandas 解释这应该应用于列集(您可能认为这是默认设置,但事实并非如此,因此在应用于整个 DataFrame
时请始终记住使用它。)lambda
用于访问两列并执行功能;在这里,x
是抽象的 DataFrame
本身的任何行。基本上,这是一种进行矢量化映射的方法。它是 pandas 中最常用的工具之一,您会发现自己经常使用它。
一个很好的基础 apply
教程是 here, showing mostly applications to a single column (with the simpler syntax I mentioned, where you don't need axis=1
.) Here also 是另一个应用于多列的示例。
这可以通过
实现df2 - df1*(df2 > df1)
例如,
In [51]: df1
Out[51]:
0 0.588922
1 0.876270
2 0.276917
3 0.521514
dtype: float64
In [52]: df2
Out[52]:
0 0.628234
1 0.492461
2 0.782199
3 0.759758
dtype: float64
In [53]: df2 - df1*(df2 > df1)
Out[53]:
0 0.039312
1 0.492461
2 0.505282
3 0.238245
dtype: float64
在性能方面,目前发布的三个解决方案在 (100000, 2) 形 DataFrame 上的表现如下:
In [124]: df = pd.DataFrame()
In [125]: df['df1'] = np.random.uniform(size=10**5)
In [126]: df['df2'] = np.random.uniform(size=10**5)
In [127]: df1 = df.df1
In [128]: df2 = df.df2
In [130]: %timeit df.apply(lambda x : x["df2"] if x["df1"] > x["df2"] else x["df2"] - x["df1"], axis=1)
1 loop, best of 3: 8.97 s per loop
In [131]: %timeit df2.where(df1 > df2, df2 - df1)
100 loops, best of 3: 3.57 ms per loop
In [132]: %timeit df2 - df1*(df2 > df1)
1000 loops, best of 3: 1.61 ms per loop