Python 如何使用,带条件的groupby,然后在DataFrame中使用cumcount
我有以下数据集:Python 如何使用,带条件的groupby,然后在DataFrame中使用cumcount,python,pandas,Python,Pandas,我有以下数据集: df = pd.DataFrame( [ ['John', 3, Yes], ['John', 4, No], ['Alex', 2, No], ['Alex', 6, No], ['John', 7, No], ['John', 2, Yes], ['Alex', 1, Yes] ], columns = ['Name', 'TestType','T
df = pd.DataFrame(
[
['John', 3, Yes],
['John', 4, No],
['Alex', 2, No],
['Alex', 6, No],
['John', 7, No],
['John', 2, Yes],
['Alex', 1, Yes]
], columns = ['Name', 'TestType','Test'])
给我:
print(df):
Name TestType Test
John 3 Yes
John 4 No
Alex 2 No
Alex 6 No
John 7 No
John 2 Yes
Alex 1 Yes
该表是按时间顺序排列的,因此我试图实现的是TestType
小于5的测试的最新计数,以及TestType
小于5的人员所进行的测试的百分比计数
我希望输出为:
print (df):
Name TestType Test TestsUnder5 TestPCunder5
John 3 Yes 1 100%
John 4 No 2 50%
Alex 2 No 1 0%
Alex 6 Yes 1 0%
John 7 No 2 50%
John 2 Yes 3 67%
Alex 1 Yes 2 50%
我想我需要使用
groupby
和cumsum
,但不确定如何指定条件,然后执行计算。任何帮助都将不胜感激 快到了!您可以将数学运算符应用于布尔级数,这会将它们强制为整数0或1。对于TestsUnder5,看起来这可能会起作用:
df['TestsUnder5']=(df.TestType<5).groupby(df.Name).apply(np.cumsum)
类似地,对于百分比,您可以使用二进制并集来获得5以下的测试:
df['TestPCunder5']=(
(
((df.Test=='Yes')&(df.TestType<5))
.groupby(df.Name).apply(np.cumsum)
)/df['TestsUnder5']
)
您的示例结果似乎是格式为“{:.0%}”的字符串。如果这就是您要查找的内容,则可以将此列强制为字符串:
df['TestPCunder5']=df['TestPCunder5'].apply(“{.0%}.”格式)
快到了!您可以将数学运算符应用于布尔级数,这会将它们强制为整数0或1。对于TestsUnder5,看起来这可能会起作用:
df['TestsUnder5']=(df.TestType<5).groupby(df.Name).apply(np.cumsum)
类似地,对于百分比,您可以使用二进制并集来获得5以下的测试:
df['TestPCunder5']=(
(
((df.Test=='Yes')&(df.TestType<5))
.groupby(df.Name).apply(np.cumsum)
)/df['TestsUnder5']
)
您的示例结果似乎是格式为“{:.0%}”的字符串。如果这就是您要查找的内容,则可以将此列强制为字符串:
df['TestPCunder5']=df['TestPCunder5'].apply(“{.0%}.”格式)
这是我的方法:
newdf = (df.assign(TestUnder5=df.TestType.lt(5),
TestTaken=df.TestType.lt(5) & df.Test.eq('Yes')
)
.groupby('Name')
[['TestUnder5','TestTaken']]
.cumsum()
)
# update original dataframe
df['TestUnder5'] = newdf['TestUnder5']
df['TestPCunder5'] = newdf['TestTaken']/newdf['TestUnder5']
输出:
Name TestType Test TestUnder5 TestPCunder5
0 John 3 Yes 1.0 1.000000
1 John 4 No 2.0 0.500000
2 Alex 2 No 1.0 0.000000
3 Alex 6 No 1.0 0.000000
4 John 7 No 2.0 0.500000
5 John 2 Yes 3.0 0.666667
6 Alex 1 Yes 2.0 0.500000
这是我的方法:
newdf = (df.assign(TestUnder5=df.TestType.lt(5),
TestTaken=df.TestType.lt(5) & df.Test.eq('Yes')
)
.groupby('Name')
[['TestUnder5','TestTaken']]
.cumsum()
)
# update original dataframe
df['TestUnder5'] = newdf['TestUnder5']
df['TestPCunder5'] = newdf['TestTaken']/newdf['TestUnder5']
输出:
Name TestType Test TestUnder5 TestPCunder5
0 John 3 Yes 1.0 1.000000
1 John 4 No 2.0 0.500000
2 Alex 2 No 1.0 0.000000
3 Alex 6 No 1.0 0.000000
4 John 7 No 2.0 0.500000
5 John 2 Yes 3.0 0.666667
6 Alex 1 Yes 2.0 0.500000
这太棒了。非常感谢@Michale Delgado!这对我来说很有意义,所以我应该能够将这些应用到其他专栏中。这太棒了。非常感谢@Michale Delgado!这对我来说是有意义的,所以应该能够将这些应用到其他专栏。非常感谢你的回复!我最终选择了Michale的解决方案,但这看起来同样不错!非常感谢您的回复!我最终选择了Michale的解决方案,但这看起来同样不错!