函数应用到GROUPBY功能
我想看看有多少持续增加,并且第一个元素和最后一个元素之间的差别,在GROUPBY。但是我不能在groupby上应用这个函数。 groupby之后,它是一个列表吗? “apply”和“agg”有什么区别?对不起,我刚刚触摸了python几天。函数应用到GROUPBY功能
def promotion(ls):     pro =0 
    if len(ls)>1: 
     for j in range(1,len(ls)): 
      if ls[j]>ls[j-1]: 
       pro + = 1 
    return pro 
def growth(ls): 
    head= ls[0] 
    tail= ls[len(ls)-1] 
    gro= tail-head 
    return gro 
titlePromotion= JobData.groupby("candidate_id")["TitleLevel"].apply(promotion) 
titleGrowth= JobData.groupby("candidate_id")["TitleLevel"].apply(growth) 
的数据是:
candidate_id TitleLevel  othercols 1     2    foo 
2     1    bar 
2     2    goo 
2     1    gar 
The result should be 
titlePromotion 
candidate_id 
1     0 
2     1 
titleGrowth 
candidate_id 
1    0 
2    0 
回答:
import pandas as pd def promotion(ls): 
    return (ls.diff() > 0).sum() 
def growth(ls): 
    return ls.iloc[-1] - ls.iloc[0] 
jobData = pd.DataFrame(
    {'candidate_id': [1, 2, 2, 2], 
    'TitleLevel': [2, 1, 2, 1]}) 
grouped = jobData.groupby("candidate_id") 
titlePromotion = grouped["TitleLevel"].agg(promotion) 
print(titlePromotion) 
# candidate_id 
# 1    0 
# 2    1 
# dtype: int64 
titleGrowth = grouped["TitleLevel"].agg(growth) 
print(titleGrowth) 
# candidate_id 
# 1    0 
# 2    0 
# dtype: int64 
一些提示:
如果定义泛型函数
def foo(ls):     print(type(ls)) 
和呼叫
jobData.groupby("candidate_id")["TitleLevel"].apply(foo) Python将打印
<class 'pandas.core.series.Series'> 这是一个庸俗的,但发现,调用jobData.groupby(...)[...].apply(foo)传递一个Series到foo有效途径。
的apply方法对于每个组调用foo一次。它可以返回一个Series或DataFrame,并将所得的块粘在一起。它可以使用applyfoo时返回一个对象,例如数值或字符串,但在这种情况下,我认为使用agg是优选的。一个典型的用例使用apply是当你想,说,广场上组和每一个值。因此需要返回相同形状的新组。
的transform方法也是在这种情况下非常有用 - 当你想变换每个值的组中,因此需要返回相同形状的东西 - 但结果可能比用apply因为不同一个不同的对象可能被传递到foo(例如,当使用transform时,分组数据帧的每一列将被传递到foo,而使用apply时整个组将被传递到foo。理解这个的最简单方法是试验一个简单的数据帧和通用foo)
的agg方法对于每个组调用foo一次,但不像apply它应该返回每组一个数字。该基团聚集成的值。使用agg的典型用例是当您要计算组中的项目数时。
您可以调试并理解了什么错了你原来的代码通过使用通用foo功能:
In [30]: grouped['TitleLevel'].apply(foo) 0 2 
Name: 1, dtype: int64 
-------------------------------------------------------------------------------- 
1 1 
2 2 
3 1 
Name: 2, dtype: int64 
-------------------------------------------------------------------------------- 
Out[30]: 
candidate_id 
1    None 
2    None 
dtype: object 
这说明你正在传递到foo系列。请注意,在第二个系列中,索引值是1和2。因此ls[0]产生了一个KeyError,因为在第二个系列中没有值为0的标签。
你真正想要的是系列中的第一项。这是iloc的用途。
因此总结一下,使用ls[label]来选择索引值为label的系列的行。使用ls.iloc[n]选择系列的第n行。
因此,与变化的量最少的解决您的代码,你可以使用
def promotion(ls):     pro =0 
    if len(ls)>1: 
     for j in range(1,len(ls)): 
      if ls.iloc[j]>ls.iloc[j-1]: 
       pro += 1 
    return pro 
def growth(ls): 
    head= ls.iloc[0] 
    tail= ls.iloc[len(ls)-1] 
    gro= tail-head 
    return gro 
回答:
VAR0 VAR1 1  1 
1  2 
1  3 
1  4 
2  5 
2  6 
2  7 
2  8 
,你可以强制使用拉姆达在应用这样的:
下面的代码会。减去从第一个
grp = df.groupby('VAR0')['VAR1'].apply(lambda x: x.iloc[0] - x) ,如果你尝试所有的值与总比分
grp = df.groupby('VAR0')['VAR1'].agg(lambda x: x.iloc[0] - x) 它不会工作,因为AGG需要,如果你减去一个特定细胞的值来获得一个价值为每个组
,有AGG和应用,他们都为每个一个值之间没有差别组
grp = df.groupby('VAR0')['VAR1'].apply(lambda x: x.iloc[0] - x.iloc[-1]) grp = df.groupby('VAR0')['VAR1'].agg(lambda x: x.iloc[0] - x.iloc[-1]) 
print grp 
VAR0 
1  -3 
2  -3 
Name: VAR1, dtype: int64 
如果您想例如,从上一行每。减去行值(以获取每一行的增量),可以使用转换这样的:
grp = df.groupby('VAR0') def subtr(x): 
    y=x.copy() 
    for i in range(1,len(x.index)): 
     x.iloc[i]=y.iloc[i]-y.iloc[i-1] 
    return x 
new_var = grp['VAR1'].transform(subtr) 
print new_var 
0 1 
1 1 
2 1 
3 1 
4 5 
5 1 
6 1 
7 1 
Name: VAR1, dtype: int64 
或更容易,为这个特殊的问题:
grp = df.groupby('VAR0')['VAR1'].apply(lambda x: x - x.shift()) 以上是 函数应用到GROUPBY功能 的全部内容, 来源链接: utcz.com/qa/261342.html


