Python 如何比较大熊猫的群体大小
也许我的想法是错误的,但我想不出一个简单的方法在熊猫身上做到这一点。我试图获得一个数据帧,该数据帧通过高于设定点的计数值与低于设定点的计数值之间的关系进行过滤。更为复杂的是 人为的例子:假设我有一个关于人的数据集,以及他们在几个测试中的分数: Person | day | test score | ---------------------------- Bob 1 10 Bob 2 40 Bob 3 45 Mary 1 30 Mary 2 35 Mary 3 45Python 如何比较大熊猫的群体大小,python,pandas,Python,Pandas,也许我的想法是错误的,但我想不出一个简单的方法在熊猫身上做到这一点。我试图获得一个数据帧,该数据帧通过高于设定点的计数值与低于设定点的计数值之间的关系进行过滤。更为复杂的是 人为的例子:假设我有一个关于人的数据集,以及他们在几个测试中的分数: Person | day | test score | ---------------------------- Bob 1 10 Bob 2 40 Bob 3 45 Mary 1 30
我认为使用groupby和aggregations将每个列生成为pd.Series,然后在最后将它们粘贴在一起是有意义的
df = pd.DataFrame([['Bob',1,10],['Bob',2,40],['Bob',3,45],
['Mary',1,30],['Mary',2,35],['Mary',3,45]], columns=
['Person','day', 'test score'])
df_group = df.groupby('Person')
above_count = df_group.apply(lambda x: x[x['test score'] >= 40]['test score'].count())
above_count.name = 'test score above_count'
total_count = df_group['test score'].agg(np.size)
total_count.name = 'total'
test_mean = df_group['test score'].agg(np.mean)
test_mean.name = 'score mean'
results = pd.concat([above_count, total_count, test_mean])
我认为使用groupby和aggregations将每个列生成为pd.Series,然后在最后将它们粘贴在一起是有意义的
df = pd.DataFrame([['Bob',1,10],['Bob',2,40],['Bob',3,45],
['Mary',1,30],['Mary',2,35],['Mary',3,45]], columns=
['Person','day', 'test score'])
df_group = df.groupby('Person')
above_count = df_group.apply(lambda x: x[x['test score'] >= 40]['test score'].count())
above_count.name = 'test score above_count'
total_count = df_group['test score'].agg(np.size)
total_count.name = 'total'
test_mean = df_group['test score'].agg(np.mean)
test_mean.name = 'score mean'
results = pd.concat([above_count, total_count, test_mean])
可以使用groupby对象上的
.agg()
进行求和和和平均,但阈值函数强制您执行以下操作
未经测试,但类似的方法应该有效:
df.groupby('Person').apply(lambda x: sum(x > 40), sum(x), mean(x))
您可以使lambda函数成为一个更复杂的常规函数,它可以实现您想要的所有标准/功能。求和和和平均可以使用groupby对象上的
.agg()
来完成,但是阈值函数强制您执行一个简单的操作
未经测试,但类似的方法应该有效:
df.groupby('Person').apply(lambda x: sum(x > 40), sum(x), mean(x))
您可以使lambda函数成为一个更复杂的常规函数,它可以实现您想要的所有条件/功能。有一种简单的方法可以做到这一点
import pandas as pd
import numpy as np
data = '''Bob 1 10
Bob 2 40
Bob 3 45
Mary 1 30
Mary 2 35
Mary 3 45'''
data = [d.split() for d in data.split('\n')]
data = pd.DataFrame(data, columns=['Name', 'day', 'score'])
data.score = data.score.astype(float)
data['pass'] = (data.score >=40)*1
data['total'] = 1
您可以添加两列以便于对数据进行计算。结果应该是这样的
Name day score pass total
0 Bob 1 10 0 1
1 Bob 2 40 1 1
2 Bob 3 45 1 1
3 Mary 1 30 0 1
4 Mary 2 35 0 1
5 Mary 3 45 1 1
Name score pass total mean score pass ratio
0 Bob 95 2 3 31.666667 0.666667
1 Mary 110 1 3 36.666667 0.333333
现在你总结一下数据
summary = data.groupby('Name').agg(np.sum).reset_index()
summary['mean score'] = summary['score']/summary['total']
summary['pass ratio'] = summary['pass']/summary['total']
print summary
结果看起来像这样
Name day score pass total
0 Bob 1 10 0 1
1 Bob 2 40 1 1
2 Bob 3 45 1 1
3 Mary 1 30 0 1
4 Mary 2 35 0 1
5 Mary 3 45 1 1
Name score pass total mean score pass ratio
0 Bob 95 2 3 31.666667 0.666667
1 Mary 110 1 3 36.666667 0.333333
现在,您可以随时根据通过率筛选出名称…有一种简单的方法可以做到这一点
import pandas as pd
import numpy as np
data = '''Bob 1 10
Bob 2 40
Bob 3 45
Mary 1 30
Mary 2 35
Mary 3 45'''
data = [d.split() for d in data.split('\n')]
data = pd.DataFrame(data, columns=['Name', 'day', 'score'])
data.score = data.score.astype(float)
data['pass'] = (data.score >=40)*1
data['total'] = 1
import pandas as pd
df = pd.DataFrame({'Person': ['Bob'] * 3 + ['Mary'] * 4,
'day': [1, 2, 3, 1, 2, 3, 4],
'test_score': [10, 40, 45, 30, 35, 45, 55]})
>>> df
Person day test_score
0 Bob 1 10
1 Bob 2 40
2 Bob 3 45
3 Mary 1 30
4 Mary 2 35
5 Mary 3 45
6 Mary 4 55
您可以添加两列以便于对数据进行计算。结果应该是这样的
Name day score pass total
0 Bob 1 10 0 1
1 Bob 2 40 1 1
2 Bob 3 45 1 1
3 Mary 1 30 0 1
4 Mary 2 35 0 1
5 Mary 3 45 1 1
Name score pass total mean score pass ratio
0 Bob 95 2 3 31.666667 0.666667
1 Mary 110 1 3 36.666667 0.333333
现在你总结一下数据
summary = data.groupby('Name').agg(np.sum).reset_index()
summary['mean score'] = summary['score']/summary['total']
summary['pass ratio'] = summary['pass']/summary['total']
print summary
结果看起来像这样
Name day score pass total
0 Bob 1 10 0 1
1 Bob 2 40 1 1
2 Bob 3 45 1 1
3 Mary 1 30 0 1
4 Mary 2 35 0 1
5 Mary 3 45 1 1
Name score pass total mean score pass ratio
0 Bob 95 2 3 31.666667 0.666667
1 Mary 110 1 3 36.666667 0.333333
现在,您可以根据通过率筛选出名称
import pandas as pd
df = pd.DataFrame({'Person': ['Bob'] * 3 + ['Mary'] * 4,
'day': [1, 2, 3, 1, 2, 3, 4],
'test_score': [10, 40, 45, 30, 35, 45, 55]})
>>> df
Person day test_score
0 Bob 1 10
1 Bob 2 40
2 Bob 3 45
3 Mary 1 30
4 Mary 2 35
5 Mary 3 45
6 Mary 4 55
在groupby
操作中,您可以通过字典传递不同的函数以在同一列上执行
result = df.groupby('Person').test_score.agg(
{'total': pd.Series.count,
'test_score_above_mean': lambda s: s.ge(40).sum(),
'score mean': np.mean})
>>> result
test_score_above_mean total score mean
Person
Bob 2 3 31.666667
Mary 2 4 41.250000
>>> result[result.test_score_above_mean.gt(result.total * .5)]
test_score_above_mean total score mean
Person
Bob 2 3 31.666667
在groupby
操作中,您可以通过字典传递不同的函数以在同一列上执行
result = df.groupby('Person').test_score.agg(
{'total': pd.Series.count,
'test_score_above_mean': lambda s: s.ge(40).sum(),
'score mean': np.mean})
>>> result
test_score_above_mean total score mean
Person
Bob 2 3 31.666667
Mary 2 4 41.250000
>>> result[result.test_score_above_mean.gt(result.total * .5)]
test_score_above_mean total score mean
Person
Bob 2 3 31.666667
好奇的是,使用.sum()而不是.count()有什么原因吗?
s.ge(40)
将生成布尔数组。如果将它们相加,则得到真实实例的数量。如果进行计数,就得到了观测值的数量(包括假值)。奇怪的是,使用.sum()而不是.count()有什么原因吗?s.ge(40)
将生成布尔数组。如果将它们相加,则得到真实实例的数量。如果进行计数,则得到观察数(包括假值)。我喜欢这种方法的简洁性,但我想不出一种方法来构造函数以获得我希望的结果。我喜欢这种方法的简洁性,但我想不出一种方法来构造函数以获得我希望的结果。