函数应用到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,并将所得的块粘在一起。它可以使用apply
foo
时返回一个对象,例如数值或字符串,但在这种情况下,我认为使用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