파일 1:
HOGBRM443983 -2522.00 19800826
HOGBRM445985 -2389.00 19801101
HOUSAM1891409 -1153.00 19811228
HOUSAM2004289 -650.00 19860101
HOUSAM2005991 -843.00 19860109
HOCANM388722 -1546.00 19860116
HOUSAM2007297 -1882.00 19860125
HOUSAM2007389 -1074.00 19860128
HOITAM801038516 -691.00 19860128
2열과 3열에는 각각 1열의 각 ID에 대한 생년월일 정보(년, 월, 일) 값과 값이 포함되어 있습니다. 각 출생 연도에 ID가 몇 개 있는지, 그리고 다른 연도의 ID 평균(두 번째 열)이 얼마인지 확인하고 싶습니다. 예를 들어, file1에는 1980년, 1981년, 1986년에 대한 ID가 각각 2개, 1개, 6개 있으므로 출력은 다음과 같습니다.
output:
1980 2 -2455.5
1981 1 -1153.00
1986 6 -114.33
첫 번째 열은 태어난 연도를 표시하고, 두 번째 열은 각 연도 내의 여러 ID를 표시하며, 세 번째 열은 서로 다른 연도의 ID 평균입니다.
실제 데이터가 정말 방대하다는 점을 고려하면 어떤 조언이라도 대단히 감사하겠습니다.
답변1
그리고gnu datamash
:
cut -c1-35 infile | datamash -W -g 3 count 3 mean 2
cut
생년월일에서 월과 일을 제거하려면 먼저 데이터를 처리해야 합니다(입력 샘플에 대한 확실한 선택이기 때문에 이것을 사용하고 있지만 모든 도구가 가능함).
HOGBRM443983 -2522.00 1980
HOGBRM445985 -2389.00 1980
HOUSAM1891409 -1153.00 1981
HOUSAM2004289 -650.00 1986
......
그런 다음 으로 파이프하면 됩니다 datamash
. 또한 세 번째 열이 연도별로 정렬되어 있다고 가정합니다(정렬되지 않은 경우 을
사용하세요 ).datamash -s -W -g ...
답변2
awk의 답변 :
awk '{y=substr($3,1,4); c[y]++; s[y]+=$2} END {for (y in c) {print y, c[y], (s[y]/c[y])}}' file.txt
답변3
실제 데이터베이스 사용을 고려해보세요.
사용하다Vagrant VM에서 Postgres 샌드박스 설정, 다음 단계를 사용하여 이 작업을 수행합니다.
CREATE TABLE MyData (id text, val float, bday date);
INSERT INTO MyData VALUES
('HOGBRM443983',-2522.00,'1980-08-26'),
('HOGBRM445985',-2389.00,'1980-11-01'),
('HOUSAM1891409',-1153.00,'1981-12-28'),
('HOUSAM2004289',-650.00,'1986-01-01'),
('HOUSAM2005991',-843.00,'1986-01-09'),
('HOCANM388722',-1546.00,'1986-01-16'),
('HOUSAM2007297',-1882.00,'1986-01-25'),
('HOUSAM2007389',-1074.00,'1986-01-28'),
('HOITAM801038516',-691.00,'1986-01-28')
;
SELECT
extract(year FROM bday) AS yr,
count(id) AS count,
avg(val) AS average
FROM mydata GROUP BY yr;
출력은 다음과 같습니다
yr | count | average
------+-------+-------------------
1981 | 1 | -1153
1980 | 2 | -2455.5
1986 | 6 | -1114.33333333333
(3 rows)
아마도 텍스트 처리로 이 문제를 처리할 수 있을 것입니다. 하지만 데이터가 크고 실제 데이터베이스가디자인됨이 계산을 위해. (내가 링크한 블로그 게시물에는 Postgres 샌드박스 설정을 위한 모든 단계가 포함되어 있습니다.)
답변4
밀러다음과 같은 문제를 해결하기 위해 만들어졌습니다.
$ cat hogbrm.txt | \
mlr --nidx --repifs put '$3=sub(string($3),"(....).*", "\1")' \
then stats1 -a count,mean -f 2 -g 3
1980 2 -2455.500000
1981 1 -1153.000000
1986 6 -1114.333333
문맥:
--nidx
헤더가 없고 위치 인덱스 컬럼만 있으므로 사용- 여러 개의 공백을 사용하여
--repifs
열 구분 sub
날짜의 마지막 4자리(3열)를 제거하는 데 사용됩니다 .stats1
3열로 그룹화된 2열의 개수와 평균을 계산하는 데 사용됩니다 .