在熊猫数据框中找到缺失值中最接近的有效数字

时间:2018-12-11 14:11:19

标签: python pandas

我有一个数据集,其中包含多个长度不等的缺失序列,我想查找在某些特定日期这些序列的前后出现的第一个有效数字。在下面的示例数据集中,我想找到最接近日期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 Loopsfirst_valid_index()来解决它如Pandas - find first non-null value in column中所述,但这很少发生。

我可以使用几个isnull()来解决这个问题,但是对于较大的数据集来说这非常慢,而且不够优雅,所以我真的很想听听其他建议!

5 个答案:

答案 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)

您可以使用ffillbfill创建两列,其值的前后分别为例如

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]