我有这个数据框,哪些条目是:
In [77]: df.loc[1]
Out[77]:
img 410T1_B03_S06_W2_cell1_ann.tif
immean 1302
imvar 101773
imrange 2640
imtotalvar 63321
method maxminratio
thresh 1.01
cont 8
minz 2
cent 50
zs 1
localmax F
sha 1383
tp 3
fp 44
fn 0
time 139.4
precision 0.0638298
sensitivity 1
score 0.12
Name: 1, dtype: object
使用dtypes:
In [79]: df.dtypes
Out[79]:
img category
immean int64
imvar int64
imrange int64
imtotalvar int64
method category
thresh float64
cont category
minz category
cent category
zs category
localmax category
sha category
tp float64
fp float64
fn float64
time float64
precision float64
sensitivity float64
score float64
dtype: object
我需要对它们进行'method'
分组,然后按相同的子集对它们进行分组['cont','minz','cent','zs','localmax','sha']
,完成后,获得具有最佳性能的行'score'
(同时保留其他信息)。
我已经做了一些非常脏的代码,可以完成这项工作,但是我想以正确的熊猫式方式完成它:
def multiplecond(df,listvar,listvalues):
res = df[listvar[0]]==listvalues[0]
for var,val in zip(listvar[1:],listvalues[1:]):
res = (res) & (df[var]==val)
return res
falseparams = ['cont','minz','cent','zs','localmax','sha']
falseparamsvalues = [list(df[x].values.categories) for x in falseparams]
falseparamssets = [[a,b,c,d,e,f] for a in falseparamsvalues[0]
for b in falseparamsvalues[1]
for c in falseparamsvalues[2]
for d in falseparamsvalues[3]
for e in falseparamsvalues[4]
for f in falseparamsvalues[5]]
spe = {}
for method in df.method.values.categories:
for falseparamsset in falseparamssets:
df2 = df[multiplecond(df,['method']+falseparams,[method]+falseparamsset)]
if not df2.empty:
n = method + '_'.join([''.join([str(x),str(y)]) for x,y in
zip(falseparams,falseparamsset)])
spe[n]=df2.copy()
df2 = []
for d in spe:
# get best score (=best thresh) for method
g = spe[d].groupby('img')
g = g['score'].max()
df2 += [[d,g.mean()]]
# visually verify thresh range
df2 = pd.DataFrame(df2,columns=['method','maxscore'])
df2.sort_values(by='score',ascending=False,inplace=True)
这样做的正确方法是什么?
编辑:这是我的数据框200个第一个条目的可粘贴版本http://pastebin.com/r5uAiyHU
EDIT2:感谢firelynx的回答,我设法减少了一些麻烦。这是怎么回事:
gbyimgbymet=df.groupby(['img','method','minz','zst','minshape'])
idx = [list(a[1][a[1]['score']==a[1].score.max()].index) for a in gbyimgbymet]
a=[]
for i in idx:
a+=i
bestscoresbyimgbymet = df.loc[a]
我知道那里可能会有更好的地方,特别是加入索引。firelynx的答案不太适合的原因是,我需要所有具有最大值的行,而不仅是一行,这就是argmax
返回的值。因此,我可能也无法使用该agg
方法。如我错了请纠正我。
好的,您的代码很脏,我认为您对解决方案进行了过度设计,因此,我将使用更干净的示例代码简单地为您提供一个示例,说明如何在概念上进行此操作。
我的示例数据框:
a b c othervalue
0 1 a z 100
1 1 b x 101
2 1 c y 102
3 2 d v 103
4 2 e u 104
5 2 f t 105
使用argmax
,我们可以获得组中最高值的索引。
df.groupby('a').agg({'othervalue':pd.Series.argmax})
othervalue
a
1 2
2 5
现在,我们可以在.loc
方法中使用该值来从原始数据框中获取整个行。
max_scores = df.groupby('a').agg({'othervalue':pd.Series.argmax})['othervalue']
df.loc[max_scores]
a b c othervalue
2 1 c y 102
5 2 f t 105
如果您有多个与最大值匹配的行,则必须做一些不同的事情,然后再执行一步。
a b c othervalue
0 1 a z 100
1 1 b x 101
2 1 c y 102
3 2 d v 103
4 2 e u 104
5 2 f t 105
6 1 a z 100
7 1 b x 101
8 1 c y 102
9 2 d v 103
10 2 e u 104
11 2 f t 105
在上面的示例中,首先我们获得每个组中的最大值,然后重置索引,以便可以将其用于即将进行的合并。
maxvalues_per_group = df.groupby('a').agg({'othervalue':pd.np.max})
maxvalues_per_group.reset_index(inplace=True)
使用这些值,我们再次在原始数据帧上合并,以获取与每个组中的最大值匹配的所有行。
df.merge(on=['a', 'othervalue'], right=maxvalues_per_group, how='inner')
a b c othervalue
0 1 c y 102
1 1 c y 102
2 2 f t 105
3 2 f t 105
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句