【问题标题】:Python Pandas Set Value in DataFrame where Index has Multiple Identical Label ValuesPython Pandas 在 DataFrame 中设置值,其中索引具有多个相同的标签值
【发布时间】:2018-05-21 23:01:04
【问题描述】:

我想在 pandas 数据框中的一行中设置一个值,其中行索引具有重复值,并且日期列的值是所选索引值的最大值。

我的数据框:

Index  Start_Date   End_Date   

  A      2017-10-01   2017-10-13
  B      2017-10-07   2017-10-15
  B      2017-10-18    np.Nat
  C      2017-10-09   2017-10-30

所以我想为 index 值“B”设置 End_Date,其中 Start_Date 是“B”的 Max

最好的方法是什么?

编辑:

我的数据框:

Index  Start_Date   End_Date   

  A      2017-10-01   2017-10-13
  B      2017-10-07   2017-10-15
  B      2017-10-18    np.Nat
  C      2017-10-09   2017-10-30
  D      2017-11-01    np.Nat
  E      2017-11-03   2017-11-09
  E      2017-11-13    np.Nat

通过单独的过程,我了解到 End_Date 对应于第 3 行(索引 == 'B',Start_Date == '2017-10-18 是 2017-10-25。我还分别找到了第 5 行(索引 == 'D',Start_Date == '2017-11-01' 是 2017-11-03。所以我想一次将这些值填充到 End_Date 中。因为我没有 End_Date 值最后一行 (Index = 'E', Start_Date == '2017-11-13') 将保持为空。

请注意,“D”是唯一的,而“B”不是。

输出:

我的数据框:

Index  Start_Date   End_Date   

  A      2017-10-01   2017-10-13
  B      2017-10-07   2017-10-15
  B      2017-10-18   2017-10-25
  C      2017-10-09   2017-10-30
  D      2017-11-01   2017-11-03
  E      2017-11-03   2017-11-09
  E      2017-11-13    np.Nat

并不是第 3 行和 2017-11-03 中的值 2017-10-25 来自另一个进程,我们可以假设它们存储在变量中 - 然后可用于填充初始数据帧以获得输出。

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    想通了:

    df = df.reset_index() 删除标签作为索引,并给我一个具有唯一值的数字索引

    Index     Item       Start_Date   End_Date   
    
      0          A      2017-10-01   2017-10-13
      1          B      2017-10-07   2017-10-15
      2          B      2017-10-18    np.Nat
      3          C      2017-10-09   2017-10-30
      4          D      2017-11-01    np.Nat
      5          E      2017-11-03   2017-11-09
      6          E      2017-11-13    np.Nat
    

    idx_val = df[df['Item'] == item][-1:].index.values[0]

    给我item 的索引值,我提供最大Start_Date。

    因此,如果我有一个来自我的其他进程的 item 'B' 的 End_Date 值为 '2017-10-25',我会得到最大为 Start_Date 的行的索引,对于 item B 通过使用上面的代码行。如果item == B,idx_val 将等于 2。

    然后我只需将End_Date 设置为idx_val == 2 的行:

    df.loc[idx_val, 'End_Date'] = pd.to_datetime('2017-10-25')

    结果是:

    Index     Item       Start_Date   End_Date   
    
      0          A      2017-10-01   2017-10-13
      1          B      2017-10-07   2017-10-15
      2          B      2017-10-18   2017-10-25
      3          C      2017-10-09   2017-10-30
      4          D      2017-11-01    np.Nat
      5          E      2017-11-03   2017-11-09
      6          E      2017-11-13    np.Nat
    

    【讨论】:

      【解决方案2】:
      # get the row indexes
      row_idx = df.sort_values(['Index', 'Start_Date']).duplicated(keep='last')
      
      # set values
      df.loc[row_idx, 'End_Date'] = 'Your desired value'
      

      希望对你有帮助!

      【讨论】:

      • 谢谢。关注问题。如果我尝试填充“End_Date”的索引值是唯一的,那么使用 duplicated 会引发错误,还是会简单地处理唯一行?
      • @Windstorm1981抱歉命名错误,row_idx 将只包含重复行的索引,将忽略唯一行。
      【解决方案3】:

      设置日期时间格式

      df.End_Date=pd.to_datetime(df.End_Date,errors='coerce')
      df.Start_Date=pd.to_datetime(df.Start_Date)
      

      然后我们做apply + fillna

      df['End_Date']=df.groupby('Index').apply(lambda x : x['End_Date'].fillna(x['Start_Date'].max())).values
      df
      Out[277]: 
        Index Start_Date   End_Date
      0     A 2017-10-01 2017-10-13
      1     B 2017-10-07 2017-10-15
      2     B 2017-10-18 2017-10-18
      3     C 2017-10-09 2017-10-30
      

      【讨论】:

      • 谢谢。你能把你的解决方案分解一下并解释一下吗?想确定我跟着。
      • @Windstorm1981 groupby 索引,正如你所说的你想要使用 B 的最大值,然后我们通过使用 B 的最大 Start_Date 到 B 的 End_Date 组来进行填充
      • 尝试填充选定的值。不是全部。是否有关于如何使用 set_values 的建议?我认为您的解决方案已达到目标,但并未尝试填充所有空单元格,
      • @Windstorm1981 我的方法会填充所有的 NaT 值,所以你只想填充其中的一部分?
      • 是的。正确的。所以我可能对一个组有一个 End_Date。我只想填写那个值。
      猜你喜欢
      • 2016-02-19
      • 2021-04-20
      • 2017-12-22
      • 1970-01-01
      • 2018-08-02
      • 2018-06-02
      • 2018-06-05
      • 2020-08-20
      • 1970-01-01
      相关资源
      最近更新 更多