【问题标题】:Keep row that the element is closest to 0 in specific column在特定列中保留元素最接近 0 的行
【发布时间】:2020-07-16 09:40:53
【问题描述】:

我正在尝试保留有条件的行。我的示例数据框中有两列。 Name 列包含重复的名称,Day 列包含 timedelta64[ns] 中的天数。

df

Name     Day
Andrew   23 days
Andrew   5 days
Andrew   -345 days
Andrew   84 days
Bess     2 days
Bess     -83 days
Bess     -123 days
Derek    344 days
Derek    238 days
Leslie   47 days
Leslie   543 days
Leslie   134 days
Leslie   -3 days

该操作将在 Name 列中保留每个名称最接近 0 的元素 Day 列。

所需的df

Name     Day
Andrew   5 days
Bess     2 days
Derek    238 days
Leslie   -3 days

任何帮助将不胜感激!提前致谢!!

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    由于目标是查找接近 0 的值,因此获取 Day 列中每个条目的 absolute 值,查找 minimum index 并获取这些索引上的值。这个想法来自solution@Ch3ster

    df.groupby("Name").agg(lambda x: x[x.abs().idxmin()])
    
    Name
    Andrew      5
    Bess        2
    Derek     238
    Leslie     -3
    dtype: int64
    

    【讨论】:

      【解决方案2】:

      Day列的abs值并使用Series.groupbyName上的列进行分组,并使用聚合函数idxmin获取最接近zero的值的索引,最后使用@987654324 @ 将索引映射到对应的 timedelta 值:

      s = df['Day'].abs().groupby(df['Name']).idxmin().map(df['Day'])
      

      结果:

      # print(s)
      
      Name
      Andrew     5 days
      Bess       2 days
      Derek    238 days
      Leslie    -3 days
      Name: Day, dtype: timedelta64[ns]
      

      【讨论】:

        【解决方案3】:

        这是另一种方式。 groupby()名字,求绝对差,用nsmallest(1)选最小的

         df.groupby('Name')['Day'].apply(lambda x: abs(x).nsmallest(1))
        
        
        
        Name      
        Andrew  1      5 days
        Bess    4      2 days
        Derek   8    238 days
        Leslie  12     3 days
        

        【讨论】:

        • 为什么是abs((0-x)) 而不仅仅是abs(x)
        【解决方案4】:

        假设您的数据框名为df,我会选择这样的东西。即使您的数据框中有更多列,该解决方案仍然有效。

        import numpy as np
        
        (df
         .assign(Diff_from_0=np.abs(df['Day']-0))  # assign a temporary column for the calculations
         .sort_values('Diff_from_0')  # sort values by our temporary column (ascending)
         .groupby(level=0)  # group by the index (names)
         .head(1)  # get first row (lowest diff from 0) for each unique index value
         .sort_index()  # sort the data frame by index, so that you get the same order of names
         .drop(columns='Diff_from_0')  # drop the temporary column, we do not need it anymore
        )
        

        为了完整起见,我通过以下方式创建了df

        df = pd.DataFrame({'Day': [23, 5, -345, 84, 2, -83, -123, 344, 238, 47, 543, 134, -3]}, 
                         index=['Andrew', 'Andrew', 'Andrew', 'Andrew', 'Bess', 'Bess', 'Bess', 'Derek', 'Derek', 'Leslie', 'Leslie', 'Leslie', 'Leslie'])
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-12-27
          • 2021-09-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-01-23
          • 1970-01-01
          相关资源
          最近更新 更多