Python 熊猫:上次列具有非nan值时
假设我有以下数据帧:Python 熊猫:上次列具有非nan值时,python,pandas,pandas-groupby,Python,Pandas,Pandas Groupby,假设我有以下数据帧: df = pd.DataFrame({"id": [1, 1, 1, 2, 2], "nominal": [1, np.nan, 1, 1, np.nan], "numeric1": [3, np.nan, np.nan, 7, np.nan], "numeric2": [2, 3, np.nan, 2, np.nan], "numeric3": [np.nan, 2, np.nan, np.nan, 3], "date":[pd.Timestamp(2005, 6, 22
df = pd.DataFrame({"id": [1, 1, 1, 2, 2], "nominal": [1, np.nan, 1, 1, np.nan], "numeric1": [3, np.nan, np.nan, 7, np.nan], "numeric2": [2, 3, np.nan, 2, np.nan], "numeric3": [np.nan, 2, np.nan, np.nan, 3], "date":[pd.Timestamp(2005, 6, 22), pd.Timestamp(2006, 2, 11), pd.Timestamp(2008, 9, 13), pd.Timestamp(2009, 5, 12), pd.Timestamp(2010, 5, 9)]})
作为输出,我希望获得一个数据帧,它将指示自该列的id
出现非nan值以来经过的天数。如果列具有对应日期的值,或者如果列的开头没有新的id
的值,则该值应为0。此外,这应该只对数值列进行计算。如上所述,输出数据帧应为:
output_df = pd.DataFrame({"numeric1_delta": [0, 234, 1179, 0, 362], "numeric2_delta": [0, 0, 945, 0, 362], "numeric3_delta": [0, 0, 945, 0, 0]})
期待您的回答 您可以按非空值的总和进行分组,然后减去第一个日期:
In [11]: df.numeric1.notnull().cumsum()
Out[11]:
0 1
1 1
2 1
3 2
4 2
Name: numeric1, dtype: int64
In [12]: df.groupby(df.numeric1.notnull().cumsum()).date.transform(lambda x: x.iloc[0])
Out[12]:
0 2005-06-22
1 2005-06-22
2 2005-06-22
3 2009-05-12
4 2009-05-12
Name: date, dtype: datetime64[ns]
In [13]: df.date - df.groupby(df.numeric1.notnull().cumsum()).date.transform(lambda x: x.iloc[0])
Out[13]:
0 0 days
1 234 days
2 1179 days
3 0 days
4 362 days
Name: date, dtype: timedelta64[ns]
对于多列:
ncols = [col for col in df.columns if col.startswith("numeric")]
for c in ncols:
df[c + "_delta"] = df.date - df.groupby(df[c].notnull().cumsum()).date.transform('first')
它会像numeric1=1 NaN 1 NaN 2 NaN NaN一样吗?你能详细说明吗?转换('first')你能调整你的答案来处理所有包含字符串
numeric
的列吗?我会接受答案,因为它肯定是我在问题中包含的。但是,我更新了示例,其中又包含了一列。如果您能看一看,我将不胜感激。@gorjan看起来for循环也应该在那里工作,但是如果有什么不同,请问另一个问题:)好的,一切都是一样的。唯一的补充是,如果列的开头有一个NaN
值,则该值应为0。