【问题标题】:How to apply a function only on selected rows and columns of pandas data frame?如何仅在熊猫数据框的选定行和列上应用函数?
【发布时间】:2017-10-03 07:07:41
【问题描述】:

我有以下数据框:

       id        subid        a
    1  1         1            2 
    2  1         1            10 
    3  1         1            20
    4  1         2            30
    5  1         2            35 
    6  1         2            36 
    7  1         2            40
    8  2         2            20
    9  2         2            29
    10 2         2            30

我想在“a”列上应用例如 pandas diff() 函数,但只要“id”或“subid”发生更改,并且想要将值存储在新列中,就应该重新应用该函数.

下面是我期望的df。

        id        subid        a      difference
    1  1         1            2       NaN
    2  1         1            10      8
    3  1         1            20      10
    4  1         2            30      NaN
    5  1         2            35      5
    6  1         2            36      1
    7  1         2            40      4
    8  2         2            20      NaN
    9  2         2            29      9
    10 2         2            30      1

正如可以在第 4 行和第 8 行观察到的那样,“id”或“subid”正在发生变化,因此存在 NaN 值,并且在连续行中计算 diff。

用过

    df["difference"] = df["a"].diff()

这显然适用于整个列,而不是预期的方式。我曾尝试使用 groupby,但它以某种方式提供了额外的行。

提前感谢您的任何建议。

【问题讨论】:

    标签: python pandas numpy dataframe


    【解决方案1】:

    试试这个:

    In [97]: df['difference'] = df.groupby(['id','subid'])['a'].diff()
    
    In [98]: df
    Out[98]:
        id  subid   a  difference
    1    1      1   2         NaN
    2    1      1  10         8.0
    3    1      1  20        10.0
    4    1      2  30         NaN
    5    1      2  35         5.0
    6    1      2  36         1.0
    7    1      2  40         4.0
    8    2      1  20         NaN
    9    2      1  29         9.0
    10   2      1  30         1.0
    

    【讨论】:

    • 如果您有第 11 行,例如 '11 1 1 2',这可能不起作用
    【解决方案2】:

    这是一个棘手的问题。根据您的确切措辞,您希望在 'id''subid' 更改的每个点处重置。这意味着即使它们来回变化。

    另外,diff 计算如果在 groupby 上下文中进行,则不会产生影响,所以我会预先计算它并在情况发生变化时进行屏蔽。

    i = df.id.values
    s = df.subid.values
    i_chg = np.append(False, i[:-1] != i[1:])
    s_chg = np.append(False, s[:-1] != s[1:])
    
    df.assign(difference=df.a.diff().mask(i_chg | s_chg))
    
        id  subid   a  difference
    1    1      1   2         NaN
    2    1      1  10         8.0
    3    1      1  20        10.0
    4    1      2  30         NaN
    5    1      2  35         5.0
    6    1      2  36         1.0
    7    1      2  40         4.0
    8    2      1  20         NaN
    9    2      1  29         9.0
    10   2      1  30         1.0
    

    【讨论】:

    • Yeo 当然,会这样做的。
    • 你能看看这个 [链接] (stackoverflow.com/questions/14631776/…) 我正在尝试在 df 上实现经过验证的答案。已经说明的是在单个轨迹上,其中坐标在 np 数组中,我有一个具有数千条轨迹的 df,每个轨迹都没有 (x,y) 坐标,它们可以由“id”和“subid”唯一标识组合(如上)。您能否建议我在 df 上应用“方向”和“角度”函数的方法。或者你想让我为此创建一个问题?
    • 请你看看问题here
    【解决方案3】:

    设置

    df = pd.DataFrame({'a': {1: 2, 2: 10, 3: 20, 4: 30, 5: 35, 6: 36, 7: 40, 8: 20, 9: 29, 10: 30},
     'id': {1: 1, 2: 1, 3: 1, 4: 1, 5: 1, 6: 1, 7: 1, 8: 2, 9: 2, 10: 2},
     'subid': {1: 1, 2: 1, 3: 1, 4: 2, 5: 2, 6: 2, 7: 2, 8: 1, 9: 1, 10: 1}})
    

    解决方案

    #Check for each row if the id-subid pair has changed with previous row and then calculate diff accordingly    
    df['difference'] = df.apply(lambda x: x.a - df.ix[x.name-1].a 
      if (x.name>1 and x[['id','subid']].equals(df.ix[x.name-1][['id','subid']])) 
      else np.nan, axis=1)
    
    df
    Out[368]: 
         a  id  subid  difference
    1    2   1      1         NaN
    2   10   1      1         8.0
    3   20   1      1        10.0
    4   30   1      2         NaN
    5   35   1      2         5.0
    6   36   1      2         1.0
    7   40   1      2         4.0
    8   20   2      1         NaN
    9   29   2      1         9.0
    10  30   2      1         1.0
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-11-13
      • 1970-01-01
      • 1970-01-01
      • 2021-03-21
      • 2021-02-06
      • 2019-01-24
      • 1970-01-01
      • 2021-02-22
      相关资源
      最近更新 更多