我有一个数据集,其中包含多个长度不等的缺失序列,我想查找在某些特定日期这些序列的前后出现的第一个有效数字。在下面的示例数据集中,我想找到最接近日期ColumnB
的{{1}}的有效数字。
数据样本:
2018-11-26
预期输出:
Date ColumnA ColumnB
2018-11-19 107.00 NaN
2018-11-20 104.00 NaN
2018-11-21 106.00 NaN
2018-11-22 105.24 80.00
2018-11-23 104.63 NaN
2018-11-26 104.62 NaN
2018-11-28 104.54 NaN
2018-11-29 103.91 86.88
2018-11-30 103.43 NaN
2018-12-01 106.13 NaN
2018-12-02 110.83 NaN
一些详细信息:
如果这种特殊序列是唯一一个缺少值的序列,那么我可以使用[80, 86.88]
或pandas函数For Loops
或first_valid_index()
来解决它如Pandas - find first non-null value in column中所述,但这很少发生。
我可以使用几个isnull()
来解决这个问题,但是对于较大的数据集来说这非常慢,而且不够优雅,所以我真的很想听听其他建议!
答案 0 :(得分:2)
尝试这种方式,获取索引和切片以获取第一个有效数字
idx= np.where(df['Date']=='2018-11-26')[0][0]
# idx 3
num = (df.loc[df.loc[:idx,'ColumnB'].first_valid_index(),'ColumnB'],
df.loc[df.loc[idx:,'ColumnB'].first_valid_index(),'ColumnB'])
num
(80.0, 86.879999999999995)
答案 1 :(得分:1)
您可以使用ffill
和bfill
创建两列,其值的前后分别为例如
df['before'] = df.ColumnB.ffill()
df['after'] = df.ColumnB.bfill()
然后使用loc
print (df.loc[df.Date == pd.to_datetime('2018-11-26'),['before','after']].values[0].tolist())
[80.0, 86.88]
,如果您有日期列表,则可以使用isin
:
list_dates = ['2018-11-26','2018-11-28']
print (df.loc[df.Date.isin(pd.to_datetime(list_dates)),['before','after']].values.tolist())
[[80.0, 86.88], [80.0, 86.88]]
答案 2 :(得分:1)
我会这样尝试:
import pandas as pd
import numpy as np
df_vld = df.dropna()
idx = np.argmin(abs(df_vld.index - pd.datetime(2018, 11,26)))
# 1
df_vld.loc[df_vld.index[idx]]
Out:
ColumnA 103.91
ColumnB 86.88
Name: 2018-11-29 00:00:00, dtype: float64
答案 3 :(得分:1)
[df['ColumnB'].ffill().loc['2018-11-26'], df['ColumnB'].bfill().loc['2018-11-26']]
答案 4 :(得分:1)
这是一种方法:
t = '2018-11-26'
寻找日期t
的索引:
ix = df.loc[df.Date==t].index.values[0]
保留ColumnB
中非空值的位置:
non_nulls = np.where(~df.ColumnB.isnull())[0]
获取上下两个最接近的非空值:
[df.loc[non_nulls[non_nulls < ix][-1],'ColumnB']] + [df.loc[non_nulls[non_nulls > ix][0],'ColumnB']]
[80.0, 86.88]