python pandas:groupby apply函数查看前一行

时间:2014-07-10 16:03:38

标签: python pandas

我有一个数据集,我想添加一列来表示某些计算的结果(它复杂)需要在每个组中完成计算,每个行值依赖于它上面的行。这是我到目前为止的代码和所需输出的简单示例:

修改1 所以我在下面更新了我的代码,也许我不理解apply如何工作,但我认为这会执行两次(每组一次)。然后,我的函数将遍历这些执行中的每一行。我仍然感到困惑的是为什么它要去3次......我想"被执行"会打印5次。对此的想法?

编辑2 我的返回功能上的缩进错了。修好了。谢谢你的帮助!

import pandas as pd

df = pd.DataFrame({'type' : ['foo', 'foo', 'foo', 'bar','bar'], 'cost' : [1, 4, 2, 8,9]})
df['class'] = np.nan

def customFunction(test_df):
    print np.shape(test_df)
    iteration = 1
    for currRow in test_df.iterrows():
        print 'executed'
        if iteration == 1:
            test_df['class'] = 'first'
        else:
            if currRow[1]['cost'] > priorCost:
                test_df['class'] = 'greater'
            elif currRow[1]['cost'] < priorCost:
                test_df['class'] = 'less'
            else:
                test_df['class'] = 'equal'

        iteration += 1        
        priorCost = currRow[1]['cost']

    return test_df

grouped_df = df.groupby(['type']).apply(customFunction)

输出:

(2, 2)
executed
(2, 2)
executed
(3, 2)
executed
   cost type  class
0     1  foo  first
1     4  foo  first
2     2  foo  first
3     8  bar  first
4     9  bar  first

1 个答案:

答案 0 :(得分:2)

到目前为止,我会给你 - 我现在需要休息一下,但是:

df = pd.DataFrame(pd.read_clipboard())
df.set_index('type', inplace=True)
test = df.groupby(level=0).apply(lambda x: x.cost.diff())

给我(因为diff()计算列w.r.t.第一个条目内的差异)

Out[160]: 
type
bar     type
bar    NaN
bar      1
Name: cost, dtype: ...
foo     type
foo    NaN
foo      3
foo     -2
Name: co...
dtype: object

因此,这包含您需要的所有信息。目前,我正在努力将这些信息合并回原始数据帧。 df['differences'] = test造成了巨大的混乱。

<强>更新

我快到了:

>>> df['differences'] = test[1].append(test[0])
>>> df.loc[df['differences'] > 0, 'inWords'] = 'greater'   
>>> df.loc[df['differences'] < 0, 'inWords'] = 'lesser' 
>>> df.loc[df['differences'].isnull(), 'inWords'] = 'first' 
>>> df
Out[184]: 
      cost  differences  inWords
type                            
foo      1          NaN    first
foo      4            3  greater
foo      2           -2   lesser
bar      8          NaN    first
bar      9            1  greater

因此,唯一需要的是通用表达式而不是test[1].append(test[0])。也许其他人可以在这里筹码?

更新2

回复您的评论:每当您为apply()定义功能时,

def compareSomethingWithinAGroup(group):
    someMagicHappens()
    return someValues

您可以访问所有标准pandas功能以及功能内的整个组。那么,你可以创建所有复杂的行依赖魔法,无论它是什么。您唯一需要注意的事项是:someValues必须是Seriesdataframe,只有一列,其中包含的行数与group的行数相同。只要您返回此类someValues,您就可以随时df['resultOfSomethingComplicated'] = df.groupby(level=0).apply(compareSomethingWithinAGroup),并使用回复中的所有行。