函数应用到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)传递一个Seriesfoo有效途径。


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

回到顶部