np.where 对 np.nan 的处理(NaN 被评估为值 < 0)
np.where treatment of np.nan (NaNs evaluated as value < 0)
我正在使用 np.where 对浮点数进行逻辑测试以确定值是 > 还是 < 0。由于 pandas 数据帧中有 np.nan 个值计算,我希望 np.where 函数对 np.nan 行进行 "ignore" - 换句话说,将该行保留为 np.nan。我该怎么做?
这是一个包含一些虚拟数据的示例。
import pandas as pd
import numpy as np
#create some dummy data with datetime index
prices = [100, 99, 98, 101, 102, 99]
dates = pd.date_range(start='1/1/2018', end='1/06/2018')
so_df = pd.DataFrame(prices, index=dates)
so_df.columns = ['Close']
#calculate daily % changes
so_df['pct_change'] = so_df.Close.pct_change()
#logic test to determine if pct_change > 0 or not
so_df['greater_zero?'] = np.where(so_df['pct_change'] > 0, 1, 0)
查看数据框,我们可以看到第一行是 np.nan,但 numpy 将其评估为小于零的值,这是不正确的。这应该只是一个 np.nan。
Close pct_change greater_zero?
2018-01-01 100 NaN 0
2018-01-02 99 -0.010000 0
2018-01-03 98 -0.010101 0
2018-01-04 101 0.030612 1
2018-01-05 102 0.009901 1
2018-01-06 99 -0.029412 0
查看 np.where documentation 似乎没有关于如何处理 np.nan 值的嵌入式参数。我也曾尝试嵌入多个 np.where 函数,但无法使其正常工作。还有其他想法吗?
您可以使用 Series.mask
来设置 NaN
值:
so_df['greater_zero?'] = np.where(so_df['pct_change'] > 0, 1, 0)
so_df['greater_zero?'].mask(so_df['pct_change'].isna(),np.nan,inplace=True)
print(so_df)
Close pct_change greater_zero?
2018-01-01 100 NaN NaN
2018-01-02 99 -0.010000 0.0
2018-01-03 98 -0.010101 0.0
2018-01-04 101 0.030612 1.0
2018-01-05 102 0.009901 1.0
2018-01-06 99 -0.029412 0.0
so_df['greater_zero?'].where(so_df['pct_change'].notna(),np.nan,inplace=True)
您可以这样使用 np.where:
so_df['greater_zero?'] = np.where(np.isnan(so_df['pct_change']), so_df['pct_change'], (so_df['pct_change'] > 0).astype(int))
print(so_df)
输出
Close pct_change greater_zero?
2018-01-01 100 NaN NaN
2018-01-02 99 -0.010000 0.0
2018-01-03 98 -0.010101 0.0
2018-01-04 101 0.030612 1.0
2018-01-05 102 0.009901 1.0
2018-01-06 99 -0.029412 0.0
基本上NaN在哪里使用相同的值否则直接使用比较的值
这可能对您不再有用,但您可以利用 NaN
乘以任何值 returns NaN
这一事实。所以 one-line 解决方案是:
so_df['greater_zero?'] = np.where(so_df['pct_change'] > 0, 1, 0*so_df['pct_change'])
print(so_df)
Close pct_change greater_zero?
2018-01-01 100 NaN NaN
2018-01-02 99 -0.010000 -0.0
2018-01-03 98 -0.010101 -0.0
2018-01-04 101 0.030612 1.0
2018-01-05 102 0.009901 1.0
2018-01-06 99 -0.029412 -0.0
我正在使用 np.where 对浮点数进行逻辑测试以确定值是 > 还是 < 0。由于 pandas 数据帧中有 np.nan 个值计算,我希望 np.where 函数对 np.nan 行进行 "ignore" - 换句话说,将该行保留为 np.nan。我该怎么做?
这是一个包含一些虚拟数据的示例。
import pandas as pd
import numpy as np
#create some dummy data with datetime index
prices = [100, 99, 98, 101, 102, 99]
dates = pd.date_range(start='1/1/2018', end='1/06/2018')
so_df = pd.DataFrame(prices, index=dates)
so_df.columns = ['Close']
#calculate daily % changes
so_df['pct_change'] = so_df.Close.pct_change()
#logic test to determine if pct_change > 0 or not
so_df['greater_zero?'] = np.where(so_df['pct_change'] > 0, 1, 0)
查看数据框,我们可以看到第一行是 np.nan,但 numpy 将其评估为小于零的值,这是不正确的。这应该只是一个 np.nan。
Close pct_change greater_zero?
2018-01-01 100 NaN 0
2018-01-02 99 -0.010000 0
2018-01-03 98 -0.010101 0
2018-01-04 101 0.030612 1
2018-01-05 102 0.009901 1
2018-01-06 99 -0.029412 0
查看 np.where documentation 似乎没有关于如何处理 np.nan 值的嵌入式参数。我也曾尝试嵌入多个 np.where 函数,但无法使其正常工作。还有其他想法吗?
您可以使用 Series.mask
来设置 NaN
值:
so_df['greater_zero?'] = np.where(so_df['pct_change'] > 0, 1, 0)
so_df['greater_zero?'].mask(so_df['pct_change'].isna(),np.nan,inplace=True)
print(so_df)
Close pct_change greater_zero?
2018-01-01 100 NaN NaN
2018-01-02 99 -0.010000 0.0
2018-01-03 98 -0.010101 0.0
2018-01-04 101 0.030612 1.0
2018-01-05 102 0.009901 1.0
2018-01-06 99 -0.029412 0.0
so_df['greater_zero?'].where(so_df['pct_change'].notna(),np.nan,inplace=True)
您可以这样使用 np.where:
so_df['greater_zero?'] = np.where(np.isnan(so_df['pct_change']), so_df['pct_change'], (so_df['pct_change'] > 0).astype(int))
print(so_df)
输出
Close pct_change greater_zero?
2018-01-01 100 NaN NaN
2018-01-02 99 -0.010000 0.0
2018-01-03 98 -0.010101 0.0
2018-01-04 101 0.030612 1.0
2018-01-05 102 0.009901 1.0
2018-01-06 99 -0.029412 0.0
基本上NaN在哪里使用相同的值否则直接使用比较的值
这可能对您不再有用,但您可以利用 NaN
乘以任何值 returns NaN
这一事实。所以 one-line 解决方案是:
so_df['greater_zero?'] = np.where(so_df['pct_change'] > 0, 1, 0*so_df['pct_change'])
print(so_df)
Close pct_change greater_zero?
2018-01-01 100 NaN NaN
2018-01-02 99 -0.010000 -0.0
2018-01-03 98 -0.010101 -0.0
2018-01-04 101 0.030612 1.0
2018-01-05 102 0.009901 1.0
2018-01-06 99 -0.029412 -0.0