提问人:Fakir 提问时间:7/11/2019 最后编辑:Scott BostonFakir 更新时间:7/12/2019 访问量:200
查找百分比的更有效方法
A more efficient way to find percentage
问:
从使用 groupby 后的数据帧中想要识别成功/不成功 率。由于我对 Python 和 pandas 的了解有限,虽然我做到了,但看起来效率低下且笨拙。一定有一些更简单有效的方法。任何帮助将不胜感激。
BldgID BldHt Device Date Time Result
1213 35 758 20181120 105550 OK
1213 35 758 20181120 105540 NG
1112 40 780 20181120 003102 OK
1117 26 790 20181120 002557 OK
1111 65 780 20181120 002102 NG
1214 80 758 20181120 001600 OK
2902 34 780 20181119 005410 OK
1232 90 780 20181119 001410 OK
1222 75 760 20181119 010552 OK
1214 80 758 20181119 010052 OK
1214 80 758 20181119 005553 NG
1246 16 790 20181119 004556 OK
1128 15 758 20181119 004552 OK
1128 15 758 20181119 004552 OK
1211 30 790 20181119 003557 NG
1211 30 790 20181119 003558 OK
下面是数据帧 (csv)。首先,我想将 [BldgID, BldHt, Device] 并找到它们占结果的百分比,即 OK/OK+NG。我做了什么 是,将“OK”更改为“1”,将“NG”更改为“0”。将所有“OK”求和。要查找 总数 (OK+NG),我在更改其值 (1 & 0) 并计算总数量。否则,它不计算 NGThen 将它们除以找到“OK”的百分比。
df = pd.read_csv("data.csv")
df1 = df.groupby(['BldgID','Device'])['Result'].agg('sum').reset_index()
df1 = df.replace({'OK':1, 'NG': 0})
df1 = df1.groupby(['BldgID','Device'])['Result'].agg('sum').reset_index()
df1['NumOKs'] = df1['Result']
# used the original df i.e. change OK=1, NG=0, to count the total num of
# OK+NG
df2 = df.groupby(['BldgID','Device'])
['Result'].agg('count').reset_index()
df2['sum'] = mel_df2['Result']
df2.drop(['Result'], axis=1, inplace=True)
df3 = pd.concat([df1['NumOKs'], df2['sum']], axis=1, keys=
['NumOKs','sum'])
df3.head(10)
# sum represents OK+NG
NumOKs sum
0 2 2
1 6 6
2 2 2
3 2 2
4 2 2
5 3 4
6 3 3
7 3 3
8 2 3
9 3 3
我得到了我想要的,但它看起来非常丑陋且效率低下。但是用我的 知识有限,我必须快速找到一些东西,它有效。想要 以更好、更简单的方式实现这一目标。 注意:结果可能无法完全再现,因为我剪切粘贴了一个小 代码和结果的一部分,以解释我想要什么以及我是如何(糟糕地)做到的。
答:
2赞
Scott Boston
7/11/2019
#1
IIUC,尝试使用和布尔条件:mean
df.groupby(['BldgID', 'Device'])['Result'].apply(lambda x : (x=='OK').mean())
要将其添加到数据帧中,请执行以下操作:
df['mean_ok'] = df.groupby(['BldgID', 'Device'])['Result']\
.apply(lambda x : (x=='OK').mean())
评论
0赞
Fakir
7/11/2019
非常感谢。试过一小部分,似乎工作正常。
1赞
Fakir
7/12/2019
如何将名称以平均值为这个新生成的列 (4) 命名,以便像其他人一样访问此属性?
0赞
Fakir
7/12/2019
谢谢。我实际上尝试了完全相同的方法。但不起作用。如果我尝试使用相同的 df 名称,那么它会给出以下 TypeError: 插入列与帧索引的索引不兼容 如果我创建一个新的 df,比如说 df1 = df.groupby(['BldgID', 'Device'])['Result'].apply(lambda x : (x=='OK').mean()) 那么它不会给出错误,而是 df1.head(10) 没有显示新的列名。
1赞
Fakir
7/22/2019
添加新列已解决!只是为了在最后添加 reset_index()。也就是说,df['mean_ok'] = df.groupby(['BldgID', 'Device'])['Result']\ .apply(lambda x : (x=='OK').mean()).reset_index()
评论
df.groupby(['BldgID', 'Device'])['Result'].apply(lambda x : (x=='OK').mean())