如何仅对pandas数据框的选定行和列应用函数?

时间:2017-05-04 23:13:52

标签: python pandas numpy dataframe

我有以下数据框:

       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"上应用say例如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

在Row-4和Row-8可以观察到" id"或者" subid"正在改变,因此存在NaN值,并且在连续的行中计算diff。

已使用

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

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

提前感谢您的任何建议。

3 个答案:

答案 0 :(得分:2)

试试这个:

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

答案 1 :(得分: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

答案 2 :(得分:2)

<强>设置

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
相关问题