Python 无法计算列中唯一值的频率
我正在做一个项目,要求我计算一个学生在不同学科的课堂上出现的次数和缺席的次数,并计算他的出勤率。我有他的出勤记录如下Python 无法计算列中唯一值的频率,python,pandas,numpy,dataframe,import-from-excel,Python,Pandas,Numpy,Dataframe,Import From Excel,我正在做一个项目,要求我计算一个学生在不同学科的课堂上出现的次数和缺席的次数,并计算他的出勤率。我有他的出勤记录如下 Attend Date Subject 96 Present 09-04-2020 AM-II 69 Present 16-04-2020 AM-II 61 Present 20-04-2020 AM-II 49 Present 22-04-2020 AM-II 45 Present 23-04-2020 AM-II ... ... ... .
Attend Date Subject
96 Present 09-04-2020 AM-II
69 Present 16-04-2020 AM-II
61 Present 20-04-2020 AM-II
49 Present 22-04-2020 AM-II
45 Present 23-04-2020 AM-II
... ... ... ...
14 Present 12-04-2020 LMS
13 Absent 18-04-2020 LMS
11 Absent 19-04-2020 LMS
10 Present 25-04-2020 LMS
9 Present 26-04-2020 LMS
我正在使用python的pandas库来计算每个独特主题的“存在”和“缺席”出现的次数,但我无法做到这一点。这就是我正在做的
data=pd.read_csv("data1.csv")
#sorting data frame by Team and then By names
data.sort_values(["Subject", "Date"], axis=0,
ascending=True, inplace=True)
p = 0
a = 0
total = 0
attpercent = {}
data.set_index(["Subject"], inplace = True,
append = True, drop = False)
temp = ""
data = data.infer_objects()
for Subject, Attend in data.iterrows()
if(temp == ""):
temp = Subject
if Attend == "Present":
p = p + 1
else:
a = a + 1
else:
if(temp == Subject):
if Attend == "Present":
p = p + 1
else:
a = a + 1
else:
total = a + p
attpercent[temp] = (p * 100) / total
a = 0
p = 0
temp = Subject
if Attend == "Present":
p = p + 1
else:
a = a + 1
print(attpercent)
它显示了一个错误:
TypeError Traceback (most recent call last)
<ipython-input-65-9d7243427e5f> in <module>
18 data = data.infer_objects()
19 for Subject, Attend in data.iterrows():
---> 20 Attend = str(Attend)
21 if(temp == ""):
22 temp = Subject
TypeError: 'Series' object is not callable
TypeError回溯(最近一次调用)
在里面
18数据=数据。推断对象()
19对于受试者,参加data.iterrows():
--->20出席=str(出席)
21如果(温度=“”):
22温度=受试者
TypeError:“Series”对象不可调用
我是第一次使用熊猫,所以我对它知之甚少。我尝试使用
expert\u objects
和astypes()
转换列的类型,但仍然得到相同的错误。请提供帮助。您应该尽量避免for循环和迭代,并熟悉pandas
方法,如.groupby
、.pivot\u table
和取消堆栈
。对于此特定问题,您可以将.groupby
与.size
一起使用,然后使用.unstack
将行移动到列,并以良好的格式获取数据,以准备计算出勤率
df = df.groupby(['Subject','Attend']).size().reset_index() \
.set_index(['Subject', 'Attend']) \
.unstack(1).fillna(0).astype(int)
df.columns = df.columns.droplevel(0)
df['Attendance'] = df['Present'] / ( df['Present'] + df['Absent'])
df
输出:
Attend Absent Present Attendance
Subject
AM-II 0 5 1.0
LMS 2 3 0.6
更详细的解释
在相关列上进行.groupby
和size
后,使用.set_index(['Subject',attention'])
计算出现次数,我将在索引上设置这两列,为下一步做准备。接下来,我将atteent
移动到标题,以将此数据集放入一个良好的矩阵格式,如和Excel Pivot表。使用.unstack(1)
,我将使用我刚刚设置的第二个索引列(记住python从0
开始,所以1
现在将第二个索引列作为我的标题,基本上以一种非常方便的方式将数据帧从行重塑为列。如果我使用.unstack(0)
,它会将主题
移动到标题,这样就不会以我们想要的方式可视化数据
最后,df.columns=df.columns.droplevel(0)
从多索引中删除一个级别,使其看起来更干净,然后出勤率的计算非常简单,它将出席人数除以总人数,得到每个主题的出勤率
比如说,完整的数据包含了另一个学生专栏。根据第一个例子,你可能会尝试从这里找出如何做到这一点,但这是你可以做的
输入:
Attend Date Subject Student
96 Present 09-04-2020 AM-II Kathy
69 Present 16-04-2020 AM-II John
61 Present 20-04-2020 AM-II John
49 Present 22-04-2020 AM-II John
45 Present 23-04-2020 AM-II Kathy
14 Present 12-04-2020 LMS Kathy
13 Absent 18-04-2020 LMS Kathy
11 Absent 19-04-2020 LMS John
10 Present 25-04-2020 LMS Kathy
9 Present 26-04-2020 LMS John
代码:
代码几乎相同。您只需使用.groupby
和.set_index()
和增加.unstack
fom1
到2
,因为出席
列现在是指定的第三个索引
列
。然后,将drop\u level(1)
更改为drop\u level(0)
,因为索引上有两列
最后,如果您想要一个没有多索引的干净数据集,只需执行df=df.reset_index()
作为返回的最后一步:
Attend Student Subject Absent Present Attendance
0 John AM-II 0 3 1.000000
1 John LMS 1 1 0.500000
2 Kathy AM-II 0 2 1.000000
3 Kathy LMS 1 2 0.666667
iterrow()不返回列它将返回行,您应该使用作为索引,数据中的行。iterrow()
t您可以通过row[attribute]
和row['Subject'访问列值
谢谢您的解释性回答。但是我不明白为什么不显示“日期”列?当我试图将其放入groupby()中时,df[“出席”]不会显示正确答案,因为它会显示每天的出席率%。如果我想在特定日期后计算出席率%,我该怎么做?@YashSethia,“date”不包括在groupby中,因此它不包括在最终结果中,但您是正确的,您无论如何都不想按日期分组。要筛选af请指定一个具体的日期做'df.loc[df['date']>'09-04-2020'。groupby'..您可以用任何日期替换'09-04-2020'。希望这有帮助。请投票并接受,如果有帮助。我试着写了这个'data=data.loc[data[“date”>“01-05-2020”]。groupby(['Subject',Attend']).size().重置索引()\.设置索引(['Subject','Attend'])\.unstack(1).fillna(0).astype(int)'但它不起作用。我仍然得到所有dates@YashSerthia在groupby之前,请尝试使用data['Date']=pd.to_datetime(data['Date'],dayfirst=True)…然后尝试使用…data=data.loc[data[“Date”]>“2020-05-01”]如果出现错误,请将其发布。我使用了data[“Date”]=pd.to_datetime(data['Date'],dayfirst=True)data=data.loc[data['Date']>“01-05-2020”]但什么都没有发生。整个数据的输出仍然是。
Attend Student Subject Absent Present Attendance
0 John AM-II 0 3 1.000000
1 John LMS 1 1 0.500000
2 Kathy AM-II 0 2 1.000000
3 Kathy LMS 1 2 0.666667