Python 在一段时间内用标签回填缺失的数据
我想根据时间(1天,2天)用不同的标签回填每一列。 代码如下:Python 在一段时间内用标签回填缺失的数据,python,pandas,dataframe,missing-data,categorical-data,Python,Pandas,Dataframe,Missing Data,Categorical Data,我想根据时间(1天,2天)用不同的标签回填每一列。 代码如下: from datetime import datetime, timedelta import pandas as pd import numpy as np import random np.random.seed(11) date_today = datetime.now() ndays = 15 df = pd.DataFrame({'date': [date_today + timedelta(days=x) for
from datetime import datetime, timedelta
import pandas as pd
import numpy as np
import random
np.random.seed(11)
date_today = datetime.now()
ndays = 15
df = pd.DataFrame({'date': [date_today + timedelta(days=x) for x in range(ndays)],
'test': pd.Series(np.random.randn(ndays)), 'test2':pd.Series(np.random.randn(ndays))})
df = df.set_index('date')
df = df.mask(np.random.random(df.shape) < .7)
print(df) # this will be the dataset that I generate for this question
# my orginal data set have labels that is why I convert it to str
df['test']=df['test'].astype(str)
df['test2']=df['test2'].astype(str)
df.replace('nan', np.nan, inplace = True)
for I in df.dropna().index.values:
end=I
start=end-np.timedelta64(24,'h')
start2=end-np.timedelta64(48,'h')
df[(df.index >= start) & (df.index <= end)]=df[(df.index >= start) & (df.index <= end)].bfill()
我想要的是这样的:
我尝试了不同的方法,但我找不到一种方法来解决这个问题,bfill不获取值的任何参数,fillna只获取方法或值
test test2
date
2018-03-07 11:28:23.028856 -0.484565_2D 1.574634_2D
2018-03-08 11:28:23.028856 -0.484565_D 1.574634_D
2018-03-09 11:28:23.028856 -0.484565 1.574634
2018-03-10 11:28:23.028856 -2.653319 NaN
2018-03-11 11:28:23.028856 -0.536629_2D NaN
2018-03-12 11:28:23.028856 -0.536629_D 0.725752_2D
2018-03-13 11:28:23.028856 -0.536629 0.725752_D
2018-03-14 11:28:23.028856 -1.065603_2D 0.725752
2018-03-15 11:28:23.028856 -1.065603_D 1.549072
2018-03-16 11:28:23.028856 -1.065603 0.630080
2018-03-17 11:28:23.028856 -0.475733_D 0.732271_D
2018-03-18 11:28:23.028856 -0.475733 0.732271
2018-03-19 11:28:23.028856 NaN -0.642575
2018-03-20 11:28:23.028856 NaN -0.178093
2018-03-21 11:28:23.028856 NaN -0.573955
更新:
我的原始数据集的时间戳是非统一的,因此此代码创建类似的时间戳:
date_today = datetime.now()
ndays = 15
df = pd.DataFrame({'date': [date_today + timedelta(days=(abs(np.random.randn(1))*2)[0]*x) for x in range(ndays)],
'test': pd.Series(np.random.randn(ndays)), 'test2':pd.Series(np.random.randn(ndays))})
df1=pd.DataFrame({'date': [date_today + timedelta(hours=x) for x in range(ndays)],
'test': pd.Series(np.random.randn(ndays)), 'test2':pd.Series(np.random.randn(ndays))})
df2=pd.DataFrame({'date': [date_today + timedelta(days=x)-timedelta(seconds=100*x) for x in range(ndays)],
'test': pd.Series(np.random.randn(ndays)), 'test2':pd.Series(np.random.randn(ndays))})
df=df.append(df1)
df=df.append(df2)
df = df.set_index('date')
df = df.mask(np.random.random(df.shape) < .7)
print(df) # this will be the dataset that I generate for this question
# my orginal data set have labels that is why I convert it to str
df['test']=df['test'].astype(str)
df['test2']=df['test2'].astype(str)
df.replace('nan', np.nan, inplace = True)
date\u today=datetime.now()
星期五=15
df=pd.DataFrame({'date':[date_today+timedelta(days=(abs(np.random.randn(1))*2)[0]*x)表示范围内的x(ndays)],
“测试”:pd.Series(np.random.randn(ndays)),“测试2”:pd.Series(np.random.randn(ndays))})
df1=pd.DataFrame({'date':[date_today+timedelta(hours=x)表示范围内的x(ndays)],
“测试”:pd.Series(np.random.randn(ndays)),“测试2”:pd.Series(np.random.randn(ndays))})
df2=pd.DataFrame({'date':[date_today+timedelta(days=x)-timedelta(seconds=100*x)表示范围内的x(ndays)],
“测试”:pd.Series(np.random.randn(ndays)),“测试2”:pd.Series(np.random.randn(ndays))})
df=df.append(df1)
df=df.append(df2)
df=df.set_索引(“日期”)
df=df.mask(np.random.random(df.shape)<.7)
打印(df)#这将是我为这个问题生成的数据集
#我的原始数据集有标签,这就是我将其转换为str的原因
df['test']=df['test'].astype(str)
df['test2']=df['test2'].astype(str)
df.replace('nan',np.nan,inplace=True)
如果有人能帮我,我真的很感激
提前感谢。使用fillna和方法回填&限制2创建填充数据帧
filled = df.fillna(method='bfill', limit=2)
# filled outputs:
test test2
date
2018-03-07 16:12:25.944362 -0.484565132221 1.5746340731
2018-03-08 16:12:25.944362 -0.484565132221 1.5746340731
2018-03-09 16:12:25.944362 -0.484565132221 1.5746340731
2018-03-10 16:12:25.944362 -2.65331855926 NaN
2018-03-11 16:12:25.944362 -0.536629362235 NaN
2018-03-12 16:12:25.944362 -0.536629362235 0.725752224799
2018-03-13 16:12:25.944362 -0.536629362235 0.725752224799
2018-03-14 16:12:25.944362 -1.06560298045 0.725752224799
2018-03-15 16:12:25.944362 -1.06560298045 1.54907163337
2018-03-16 16:12:25.944362 -1.06560298045 0.630079822493
2018-03-17 16:12:25.944362 -0.475733492683 0.732271353885
2018-03-18 16:12:25.944362 -0.475733492683 0.732271353885
2018-03-19 16:12:25.944362 NaN -0.642575392433
2018-03-20 16:12:25.944362 NaN -0.178093175312
2018-03-21 16:12:25.944362 NaN -0.57395455941
创建bool数据框以指示单元格是否已填充
is_filled = df.isnull() & filled.notnull()
# is_filled outputs:
test test2
date
2018-03-07 16:12:25.944362 True True
2018-03-08 16:12:25.944362 True True
2018-03-09 16:12:25.944362 False False
2018-03-10 16:12:25.944362 False False
2018-03-11 16:12:25.944362 True False
2018-03-12 16:12:25.944362 True True
2018-03-13 16:12:25.944362 False True
2018-03-14 16:12:25.944362 True False
2018-03-15 16:12:25.944362 True False
2018-03-16 16:12:25.944362 False False
2018-03-17 16:12:25.944362 True True
2018-03-18 16:12:25.944362 False False
2018-03-19 16:12:25.944362 False False
2018-03-20 16:12:25.944362 False False
2018-03-21 16:12:25.944362 False False
创建掩码以指示需要后缀\u 1D
或\u 2D
one_d = (is_filled & ~is_filled.shift(-1).fillna(False)).applymap(lambda x: '_1D' if x else '')
two_d = (is_filled & is_filled.shift(-1).fillna(False)).applymap(lambda x: '_2D' if x else '')
suffix = pd.concat([one_d, two_d]).groupby('date').agg('max')
# suffix outputs:
test test2
date
2018-03-07 16:12:25.944362 _2D _2D
2018-03-08 16:12:25.944362 _1D _1D
2018-03-09 16:12:25.944362
2018-03-10 16:12:25.944362
2018-03-11 16:12:25.944362 _2D
2018-03-12 16:12:25.944362 _1D _2D
2018-03-13 16:12:25.944362 _1D
2018-03-14 16:12:25.944362 _2D
2018-03-15 16:12:25.944362 _1D
2018-03-16 16:12:25.944362
2018-03-17 16:12:25.944362 _1D _1D
2018-03-18 16:12:25.944362
2018-03-19 16:12:25.944362
2018-03-20 16:12:25.944362
2018-03-21 16:12:25.944362
将后缀dataframe连接到填充的dataframe将浮点转换为字符串并附加适当的后缀
final = filled.join(suffix, rsuffix='_x')
final.apply(lambda x: '{}{}'.format(x.test, x.test_x), axis=1)
# outputs:
date
2018-03-07 16:12:25.944362 -0.484565132221_2D
2018-03-08 16:12:25.944362 -0.484565132221_1D
2018-03-09 16:12:25.944362 -0.484565132221
2018-03-10 16:12:25.944362 -2.65331855926
2018-03-11 16:12:25.944362 -0.536629362235_2D
2018-03-12 16:12:25.944362 -0.536629362235_1D
2018-03-13 16:12:25.944362 -0.536629362235
2018-03-14 16:12:25.944362 -1.06560298045_2D
2018-03-15 16:12:25.944362 -1.06560298045_1D
2018-03-16 16:12:25.944362 -1.06560298045
2018-03-17 16:12:25.944362 -0.475733492683_1D
2018-03-18 16:12:25.944362 -0.475733492683
2018-03-19 16:12:25.944362 nan
2018-03-20 16:12:25.944362 nan
2018-03-21 16:12:25.944362 nan
类似地,您可以为
test2
生成填充和后缀序列。但是,我建议您将test
和test2
保留为数字类型,并将填充和延迟信息存储在单独的列中(这里的列后缀
将该信息存储在数据框final
)中。这是否类似于只向后填充两天的数据?@Usernamenotfound是的,这是正确的,在数据表中的数据中向后填充一天,然后是两天。为什么列中的值-0.536629
在日期2018-03-13 11:28:23.028856
没有在前两个日期中回填两个空值?@haleemulali应该,这是一个输入错误,我更新了问题,谢谢你注意到了。非常感谢你的回答。这是一种优雅的方式。原始数据集在日期方面并不统一。所以它的日期间隔不一致。我通过在每一列上循环来解决这个问题,但这可能不是很有效。有没有办法改变您提出的解决方案,使其能够在不重新采样的情况下处理非统一的时间戳。您能告诉我们日期是如何不统一的吗?也许有更好的方法我更新了问题以创建非统一的时间戳,感谢你的时间。我写了这个脚本来完成这项工作,但是它非常慢,对于我的数据集,对于列表中的II(df):对于df[II]中的I.dropna().index.values:end=I start=end np.timedelta64(24,'h')start2=end np.timedelta64(48,'h')s2=df[(df[II]“索引>开始=”和(DF[II] index =开始)和(DF[II] index =开始)和(DF[II]。索引I不能想到一个好的方法来做它现在,但可能你可以考虑在这个问题上提出一个赏金,以吸引其他人尝试解决方案。
final = filled.join(suffix, rsuffix='_x')
final.apply(lambda x: '{}{}'.format(x.test, x.test_x), axis=1)
# outputs:
date
2018-03-07 16:12:25.944362 -0.484565132221_2D
2018-03-08 16:12:25.944362 -0.484565132221_1D
2018-03-09 16:12:25.944362 -0.484565132221
2018-03-10 16:12:25.944362 -2.65331855926
2018-03-11 16:12:25.944362 -0.536629362235_2D
2018-03-12 16:12:25.944362 -0.536629362235_1D
2018-03-13 16:12:25.944362 -0.536629362235
2018-03-14 16:12:25.944362 -1.06560298045_2D
2018-03-15 16:12:25.944362 -1.06560298045_1D
2018-03-16 16:12:25.944362 -1.06560298045
2018-03-17 16:12:25.944362 -0.475733492683_1D
2018-03-18 16:12:25.944362 -0.475733492683
2018-03-19 16:12:25.944362 nan
2018-03-20 16:12:25.944362 nan
2018-03-21 16:12:25.944362 nan