【问题标题】:Pandas subtract datetime condition熊猫减去日期时间条件
【发布时间】:2018-11-15 06:23:49
【问题描述】:

我想遍历数据框并仅在每行中的 ID 匹配时减去日期时间。但是,如下例所示,我的 for 循环不起作用。所有 NAN 值仍在其中,我收到以下警告。我尝试了很多变体,但不明白问题所在。

我还在下面给出了所需输出数据帧的代码。修复此问题后,我想根据 Days_since 列进行条件设置,并根据以下条件为 Chg_avg_value 分配值:如果 Days_since 条目等于 NAN,则 Chg_avg_value 等于 NAN;否则,减去平均。值条目。

非常感谢。我真的在熊猫索引上苦苦挣扎。

A value is trying to be set on a copy of a slice from a DataFrame

初始数据框:

df_so_dict={'Index':[0,1,2,3,4,5,6,7,8,9],'DateOf': ['2017-08-01','2017-08-03','2017-08-04', '2017-08-07','2017-08-09','2017-08-11','2017-08-12','2017-08-02','2017-08-04','2017-08-07'],
    'ID': ['553','553','553','559','559','559','559','914','914','914'], 'Count': [4,1,3,4,9,11,4,2,10,5],
    'Avg. Value': [4.4,3,5.3,6.4,5,4.2,3.5,2,3.3,2.2]
    }
df_so_ex2=pd.DataFrame(df_so_dict)
df_so_ex2.set_index('Index',inplace=True)
df_so_ex2['DateOf'] = pd.to_datetime(df_so_ex2['DateOf'])
df_so_ex2.dtypes #ID is an object

循环:

new=1
prev=0
df_so_ex['Days_since']=np.nan

    if df_so_ex.iloc[new]['ID'] == df_so_ex.iloc[prev]['ID']:
        df_so_ex.iloc[new]['Days_since']=df_so_ex.iloc[new]['DateOf'] - df_so_ex.iloc[prev]['DateOf']
        new+=1
        prev+=1
    else:
        new+=1
        prev+=1
    print(new)
    print(prev)

所需的数据框:

df_so_dict_ans={'Index':[0,1,2,3,4,5,6,7,8,9],'DateOf': ['2017-08-01','2017-08-03','2017-08-04', '2017-08-07','2017-08-09','2017-08-11','2017-08-12','2017-08-02','2017-08-04','2017-08-07'],
    'ID': ['553','553','553','559','559','559','559','914','914','914'], 'Count': [4,1,3,4,9,11,4,2,10,5],
    'Avg. Value': [4.4,3,5.3,6.4,5,4.2,3.5,2,3.3,2.2],
    'Days_since':['nan',2,1,'nan',2,2,1,'nan',2,3],
    'Chg_avg_value':['nan',-1.4,2.3,'nan',-1.4,-0.8,-0.7,'nan',1.3,-1.1]
    }

df_so_ex_ans=pd.DataFrame(df_so_dict_ans)
df_so_ex_ans.set_index('Index',inplace=True)

【问题讨论】:

    标签: python pandas datetime dataframe


    【解决方案1】:

    使用groupby + pd.Series.diff

    g = df_so_ex2.groupby('ID')
    
    df_so_ex2['Chg_avg_value'] = g['Avg. Value'].apply(pd.Series.diff)
    df_so_ex2['Days_since'] = g['DateOf'].apply(pd.Series.diff).dt.days
    
    print(df_so_ex2)
    
           Avg. Value  Count     DateOf   ID  Chg_avg_value  Days_since
    Index                                                              
    0             4.4      4 2017-08-01  553            NaN         NaN
    1             3.0      1 2017-08-03  553           -1.4         2.0
    2             5.3      3 2017-08-04  553            2.3         1.0
    3             6.4      4 2017-08-07  559            NaN         NaN
    4             5.0      9 2017-08-09  559           -1.4         2.0
    5             4.2     11 2017-08-11  559           -0.8         2.0
    6             3.5      4 2017-08-12  559           -0.7         1.0
    7             2.0      2 2017-08-02  914            NaN         NaN
    8             3.3     10 2017-08-04  914            1.3         2.0
    9             2.2      5 2017-08-07  914           -1.1         3.0
    

    【讨论】:

    • 非常感谢。这比 for 循环要好得多。这里使用系列很聪明,就像使用组来改变值一样
    【解决方案2】:

    你可以使用groupbydiff,得到结果后,concat返回

    s=df_so_ex2.groupby('ID').apply(lambda x : pd.DataFrame({'Days_since':x['DateOf'].diff().dt.days,'Chg_avg_value':x['Avg. Value'].diff()}))
    pd.concat([df_so_ex2,s],axis = 1)
    Out[460]: 
           Avg. Value  Count     DateOf   ID  Chg_avg_value  Days_since
    Index                                                              
    0             4.4      4 2017-08-01  553            NaN         NaN
    1             3.0      1 2017-08-03  553           -1.4         2.0
    2             5.3      3 2017-08-04  553            2.3         1.0
    3             6.4      4 2017-08-07  559            NaN         NaN
    4             5.0      9 2017-08-09  559           -1.4         2.0
    5             4.2     11 2017-08-11  559           -0.8         2.0
    6             3.5      4 2017-08-12  559           -0.7         1.0
    7             2.0      2 2017-08-02  914            NaN         NaN
    8             3.3     10 2017-08-04  914            1.3         2.0
    9             2.2      5 2017-08-07  914           -1.1         3.0
    

    【讨论】:

      猜你喜欢
      • 2020-08-27
      • 1970-01-01
      • 2015-09-19
      • 2021-08-30
      • 2019-05-20
      • 2017-11-19
      • 2017-09-24
      • 2017-11-19
      相关资源
      最近更新 更多