免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 8250 | 回复: 28
打印 上一主题 下一主题

[文本处理] 去掉最大值和最小值然后求平均值 [复制链接]

论坛徽章:
32
处女座
日期:2013-11-20 23:41:20双子座
日期:2014-06-11 17:20:43戌狗
日期:2014-06-16 11:05:00处女座
日期:2014-07-22 17:30:47狮子座
日期:2014-07-28 15:38:17金牛座
日期:2014-08-05 16:34:01亥猪
日期:2014-08-18 13:34:25白羊座
日期:2014-09-02 15:03:55金牛座
日期:2014-11-10 10:23:58处女座
日期:2014-12-02 09:17:52程序设计版块每日发帖之星
日期:2015-06-16 22:20:002015亚冠之塔什干火车头
日期:2015-06-20 23:28:22
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-03-26 10:12 |只看该作者 |倒序浏览
本帖最后由 yestreenstars 于 2013-03-26 11:09 编辑

又到了春暖花开、春雨绵绵的季节了,这么好的季节就应该头脑风暴一下,我设计了这样一道题(其实是从群里抄的 ),聪明的你要多久能做出来呢?



原文本:
Peter Blue Teacher 58.40 74.32
Anne Red Student 22.33 122.32
Anne Red Student 99.39 88.22
Sue Yellow Worker 76.38 88.47
Peter Blue Teacher 77.43 28.31
Ken Black Driver 84.67 47.33
Sue Yellow Worker 64.67 73.27
Peter Blue Teacher 70.49 12.77
Sue Yellow Worker 202.69 37.34
Peter Blue Teacher 105.48 88.42

目标文本:
Anne Red Student 60.86 105.27
Peter Blue Teacher 73.96 20.54
Sue Yellow Worker 76.38 88.47
Ken Black Driver 84.67 47.33

要求:
1.如果第一列只出现过一次(比如Ken)则直接打印;
2.如果第一列出现过两次(比如Anne)则对第四列和第五列各自求平均值然后打印;
3.如果第一列出现过三次(比如Sue)则去掉第三列的最大值(比如202.69)和最小值(比如64.67)的两行,然后打印处于中间的那行;
4.如果第一列出现过四次(比如Peter)或四次以上则去掉第三列的最大值和最小值的两行,然后对其余的行的第四列和第五列各自求平均值然后打印;
5.对最后打印的顺序无要求;
6.只能用awk进行处理,不借用管道和其他命令,不能先用sort排序

论坛徽章:
60
20周年集字徽章-20	
日期:2020-10-28 14:04:3015-16赛季CBA联赛之北京
日期:2016-07-06 15:42:0715-16赛季CBA联赛之同曦
日期:2016-06-12 10:38:0915-16赛季CBA联赛之佛山
日期:2016-05-27 11:54:56黄金圣斗士
日期:2015-12-02 11:44:35白银圣斗士
日期:2015-11-25 14:32:43白银圣斗士
日期:2015-11-23 12:53:352015亚冠之布里斯班狮吼
日期:2015-10-21 16:55:482015亚冠之首尔
日期:2015-09-01 16:46:052015亚冠之德黑兰石油
日期:2015-08-31 11:39:192015亚冠之萨济拖拉机
日期:2015-08-28 21:06:5315-16赛季CBA联赛之广东
日期:2016-07-12 14:58:53
2 [报告]
发表于 2013-03-26 11:03 |只看该作者
说明有问题呀! 应该都是第一列出现一次,两次,三次,四次吧

论坛徽章:
32
处女座
日期:2013-11-20 23:41:20双子座
日期:2014-06-11 17:20:43戌狗
日期:2014-06-16 11:05:00处女座
日期:2014-07-22 17:30:47狮子座
日期:2014-07-28 15:38:17金牛座
日期:2014-08-05 16:34:01亥猪
日期:2014-08-18 13:34:25白羊座
日期:2014-09-02 15:03:55金牛座
日期:2014-11-10 10:23:58处女座
日期:2014-12-02 09:17:52程序设计版块每日发帖之星
日期:2015-06-16 22:20:002015亚冠之塔什干火车头
日期:2015-06-20 23:28:22
3 [报告]
发表于 2013-03-26 11:10 |只看该作者
回复 2# reyleon


    嘿嘿,纯属笔误,已修改。

论坛徽章:
145
技术图书徽章
日期:2013-10-01 15:32:13戌狗
日期:2013-10-25 13:31:35金牛座
日期:2013-11-04 16:22:07子鼠
日期:2013-11-18 18:48:57白羊座
日期:2013-11-29 10:09:11狮子座
日期:2013-12-12 09:57:42白羊座
日期:2013-12-24 16:24:46辰龙
日期:2014-01-08 15:26:12技术图书徽章
日期:2014-01-17 13:24:40巳蛇
日期:2014-02-18 14:32:59未羊
日期:2014-02-20 14:12:13白羊座
日期:2014-02-26 12:06:59
4 [报告]
发表于 2013-03-26 13:20 |只看该作者
本帖最后由 jason680 于 2013-03-26 13:35 编辑

回复 1# yestreenstars

Would you like this

Description: (mask them to see description)
  x ($1) for key name
  p[x] for full name
  c[x] for count
  p[x,1] for total $4
  p[x,2] for total $5
  p[x,3] for Max $4, and the same line $5 be p[x,4]
  p[x,5] for Min $4, and the same line $5 be p[x,6]



$ awk '{x=$1;p[x]=$1" "$2" "$3;if(!c[x]++)for(n=0;n++<2;)p[x,n]=p[x,n+2]=p[x,n+4]=$(n+3);else{p[x,1]+=$4;p[x,2]+=$5;if(p[x,3]<$4){p[x,3]=$4;p[x,4]=$5}if(p[x,5]>$4){p[x,5]=$4;p[x,6]=$5}}}END{for(x in c){if(c[x]<=2){x4=p[x,1]/c[x];x5=p[x,2]/c[x]}else{x4=(p[x,1]-p[x,3]-p[x,5])/(c[x]-2);x5=(p[x,2]-p[x,4]-p[x,6])/(c[x]-2)}print p[x],x4,x5}}' FILE
Ken Black Driver 84.67 47.33
Anne Red Student 60.86 105.27
Peter Blue Teacher 73.96 20.54
Sue Yellow Worker 76.38 88.47


---without x4 and x5 ----------------
$ awk '{x=$1;p[x]=$1" "$2" "$3;if(!c[x]++)for(n=0;n++<2;)p[x,n]=p[x,n+2]=p[x,n+4]=$(n+3);else{p[x,1]+=$4;p[x,2]+=$5;if(p[x,3]<$4){p[x,3]=$4;p[x,4]=$5}if(p[x,5]>$4){p[x,5]=$4;p[x,6]=$5}}}END{for(x in c){if(c[x]>=3){p[x,1]-=(p[x,3]+p[x,5]);p[x,2]-=(p[x,4]+p[x,6]);c[x]-=2}print p[x],p[x,1]/c[x],p[x,2]/c[x]}}' FILE

论坛徽章:
32
处女座
日期:2013-11-20 23:41:20双子座
日期:2014-06-11 17:20:43戌狗
日期:2014-06-16 11:05:00处女座
日期:2014-07-22 17:30:47狮子座
日期:2014-07-28 15:38:17金牛座
日期:2014-08-05 16:34:01亥猪
日期:2014-08-18 13:34:25白羊座
日期:2014-09-02 15:03:55金牛座
日期:2014-11-10 10:23:58处女座
日期:2014-12-02 09:17:52程序设计版块每日发帖之星
日期:2015-06-16 22:20:002015亚冠之塔什干火车头
日期:2015-06-20 23:28:22
5 [报告]
发表于 2013-03-26 13:55 |只看该作者
回复 4# jason680


    先顶礼膜拜一下先 太强大了,我得好好看一下~

论坛徽章:
0
6 [报告]
发表于 2013-03-26 14:08 |只看该作者
awk本身就是一门语言   虽然很简练   但是用的已经很少了  而且可读性  一样望去  真是头大

对付这种稍微复杂的问题   不如用python或者perl   虽然写的多几句   但是可读性还是不错的

论坛徽章:
13
丑牛
日期:2013-08-16 15:08:22技术图书徽章
日期:2013-11-26 10:13:40双鱼座
日期:2013-11-08 15:03:26戌狗
日期:2013-11-08 13:52:30技术图书徽章
日期:2013-11-05 14:06:30戌狗
日期:2013-10-31 11:45:42CU十二周年纪念徽章
日期:2013-10-24 15:41:34天秤座
日期:2013-10-11 14:55:08子鼠
日期:2013-09-26 19:36:35水瓶座
日期:2013-09-26 17:44:56午马
日期:2013-08-26 10:24:23丑牛
日期:2013-08-19 14:43:22
7 [报告]
发表于 2013-03-26 14:35 |只看该作者
awk写得太复杂看得真是头大

论坛徽章:
32
处女座
日期:2013-11-20 23:41:20双子座
日期:2014-06-11 17:20:43戌狗
日期:2014-06-16 11:05:00处女座
日期:2014-07-22 17:30:47狮子座
日期:2014-07-28 15:38:17金牛座
日期:2014-08-05 16:34:01亥猪
日期:2014-08-18 13:34:25白羊座
日期:2014-09-02 15:03:55金牛座
日期:2014-11-10 10:23:58处女座
日期:2014-12-02 09:17:52程序设计版块每日发帖之星
日期:2015-06-16 22:20:002015亚冠之塔什干火车头
日期:2015-06-20 23:28:22
8 [报告]
发表于 2013-03-26 14:59 |只看该作者
本帖最后由 yestreenstars 于 2013-03-26 15:14 编辑

@jason680
我自己也写了一个,应该比你那个好懂一些。
  1. awk '{a[$1]=a[$1]!=""?a[$1]" "$4:$4;b[$1,$4]=$5;NF-=2;c[$1]=$0}END{for(i in a){k=split(a[i],d," ");asort(d,e);if(k==1)print c[i],e[1],b[i,e[1]];if(k==2){m=(e[1]+e[2])/2;n=(b[i,e[1]]+b[i,e[2]])/2;print c[i],m,n}if(k>=3){for(j=2;j<k;j++){m+=e[j];n+=b[i,e[j]]}print c[i],m/(k-2),n/(k-2)}m=n=0}}'
复制代码

论坛徽章:
145
技术图书徽章
日期:2013-10-01 15:32:13戌狗
日期:2013-10-25 13:31:35金牛座
日期:2013-11-04 16:22:07子鼠
日期:2013-11-18 18:48:57白羊座
日期:2013-11-29 10:09:11狮子座
日期:2013-12-12 09:57:42白羊座
日期:2013-12-24 16:24:46辰龙
日期:2014-01-08 15:26:12技术图书徽章
日期:2014-01-17 13:24:40巳蛇
日期:2014-02-18 14:32:59未羊
日期:2014-02-20 14:12:13白羊座
日期:2014-02-26 12:06:59
9 [报告]
发表于 2013-03-26 15:39 |只看该作者
回复 8# yestreenstars


That's good for understand, but not for run time

$ wc FILE
31002 155010 744102 FILE

$ time awk '{a[$1]++;b[$1]=b[$1]?b[$1]" "$4:$4;c[$1,$4]=$5;NF-=2;d[$1]=$0}END{for(i in a){k=split(b,e," ");asort(e,f);if(a==1)print d,f[1],c[i,f[1]];if(a==2){m=(f[1]+f[2])/2;n=(c[i,f[1]]+c[i,f[2]])/2;print d,m,n}if(a>=3){for(j=2;j<k;j++){m+=f[j];n+=c[i,f[j]]}print d,m/(k-2),n/(k-2)}m=n=0}}' FILE1
Ken Black Driver 84.67 47.33
Anne Red Student 15497.8 15497.5
Peter Blue Teacher 73.96 20.54
Sue Yellow Worker 76.38 88.47

real    0m30.264s
user    0m2.040s
sys    0m27.482s

$ time awk '{x=$1;p[x]=$1" "$2" "$3;if(!c[x]++)for(n=0;n++<2;)p[x,n]=p[x,n+2]=p[x,n+4]=$(n+3);else{p[x,1]+=$4;p[x,2]+=$5;if(p[x,3]<$4){p[x,3]=$4;p[x,4]=$5}if(p[x,5]>$4){p[x,5]=$4;p[x,6]=$5}}}END{for(x in c){if(c[x]>=3){p[x,1]-=(p[x,3]+p[x,5]);p[x,2]-=(p[x,4]+p[x,6]);c[x]-=2}print p[x],p[x,1]/c[x],p[x,2]/c[x]}}' FILE1
Ken Black Driver 84.67 47.33
Anne Red Student 15497.8 15497.5
Peter Blue Teacher 73.96 20.54
Sue Yellow Worker 76.38 88.47

real    0m0.229s

user    0m0.084s
sys    0m0.088s

论坛徽章:
1
射手座
日期:2014-03-10 14:24:52
10 [报告]
发表于 2013-03-26 15:44 |只看该作者
我去天外有天啊
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP