LoginSignup
4
4

More than 5 years have passed since last update.

「言語処理100本ノック 2015」ではじめるPythonとNLPスキルのリハビリテーション(第2章前半)

Posted at

前回の更新から1か月近く・・・順調な三日坊主ぶりです。

このへんは、章のタイトルの通りUNIXコマンドを使ってやることが多いので、
pythonで書けと言われると少し面倒に感じるかも。

まずは、データセットをダウンロードして・・・。

第2章: UNIXコマンドの基礎

10. 行数のカウント

行数をカウントせよ.確認にはwcコマンドを用いよ.

filename = 'hightemp.txt'
f = open(filename, 'r')
print sum([1 for l in f])
#>>> 24

これは本当にいろんな方法があるようで・・・。
http://551sornwmc.blog109.fc2.com/blog-entry-387.html
http://stackoverflow.com/questions/845058/how-to-get-line-count-cheaply-in-python

メモリ使用量と実行速度の点では、こちらのメモリマップドファイルを使うのが良さそう。

# using memory mapped file
import mmap
def mapcount(filename):
    f = open(filename, "r+")
    buf = mmap.mmap(f.fileno(), 0)
    lines = 0
    readline = buf.readline
    while readline():
        lines += 1
    return lines

UNIXコマンドでの確認はこちら。

wc -l hightemp.txt
#>>> 24

11. タブをスペースに置換

タブ1文字につきスペース1文字に置換せよ.確認にはsedコマンド,trコマンド,もしくはexpandコマンドを用いよ.

#import re

filename = 'hightemp.txt'
f = open(filename, 'r')
lines = f.readlines()
for line in lines:
    #line_replaced =  re.sub(r'\t', r'\s', line)
    line_replaced = line.expandtabs(1)
    print line_replaced,

expandtabsなんてあるんだ。

UNIXコマンドでの確認はこちら。

cat hightemp.txt | tr '\t' ','

これ↑が一番すんなりできそう。

sed -e s/'\t'/'\s'/g hightemp.txt
#Macでうまくいかないので、あらため
sed -e s/$'\t'/$'\s'/g hightemp.txt
#あれ?

Mac OS X などに入っている BSD sed は echo や printf のようにスクリプト中の \t をタブには展開しません。

Oh...

12. 1列目をcol1.txtに,2列目をcol2.txtに保存

各行の1列目だけを抜き出したものをcol1.txtに,2列目だけを抜き出したものをcol2.txtとしてファイルに保存せよ.確認にはcutコマンドを用いよ.

filename = 'hightemp.txt'
filename_col1 = 'col1.txt'
filename_col2 = 'col2.txt'

f = open(filename, 'r')
f_col1 = open(filename_col1, 'w')
f_col2 = open(filename_col2, 'w')

lines = f.readlines()

content_col1 = [line.split()[0] + '\n' for line in lines]
content_col2 = [line.split()[1] + '\n' for line in lines]

f_col1.writelines(content_col1)
f_col2.writelines(content_col2)

f_col1.close()
f_col2.close()

一点注意としては、writelines メソッドでは改行が入らないので、
自分で追加してあげたことでしょうか。

UNIXコマンドでの確認はこちら。
うわー吐き気がするほど簡単。

cut -f1 hightemp.txt > col1.txt
cut -f2 hightemp.txt > col2.txt

13. col1.txtとcol2.txtをマージ

12で作ったcol1.txtとcol2.txtを結合し,元のファイルの1列目と2列目をタブ区切りで並べたテキストファイルを作成せよ.確認にはpasteコマンドを用いよ.

filename_col1 = 'col1.txt'
filename_col2 = 'col2.txt'
filename_col1_col2 = 'col1_col2.txt'

f_col1 = open(filename_col1, 'r')
f_col2 = open(filename_col2, 'r')
f_col1_col2 = open(filename_col1_col2, 'w')

lines_1 = f_col1.readlines()
lines_2 = f_col2.readlines()

content = [line1 + '\t' + line2 + '\n' for line1, line2 in zip(lines_1, lines_2)]

f_col1_col2.writelines(content)
f_col1_col2.close()    

f_col1.close()    
f_col2.close()    

UNIXコマンドでの確認はこちら。
簡単すぎて吐いちゃった。

paste col1.txt col2.txt > col1_col2.txt

14. 先頭からN行を出力

自然数Nをコマンドライン引数などの手段で受け取り,入力のうち先頭のN行だけを表示せよ.確認にはheadコマンドを用いよ.

knock014.py
# -*- coding: utf-8 -*-

import sys
import argparse

parser = argparse.ArgumentParser(description='Head command. Accepts an integer and a file name.')

# 行数
parser.add_argument(
    '-l', '--line',
    type = int,
    dest = 'line',
    default = 10,
    help = 'headコマンドで指定する行数に相当'
)

# ファイル名
parser.add_argument(
    '-f', '--filename',
    type = str,                     # 受け取る値の型を指定する
    dest = 'filename',              # 保存先変数名
    required = True,                # 必須項目
    help = '入力として与えるファイル名'    # --help時に表示する文
)

args = parser.parse_args()
N = args.line
filename = args.filename

# 先頭のN行を表示する
f = open(filename)
for x in xrange(N):
    print f.next().strip()
f.close()

上記を実行すると。

python knock014.py -l 3 -f hightemp.txt
# >>>高知県  江川崎   41  2013-08-12
# >>>埼玉県  熊谷  40.9    2007-08-16
# >>>岐阜県  多治見   40.9    2007-08-16

python knock014.py -l 3 -f hightemp.txt
# >>>高知県  江川崎   41  2013-08-12
# >>>埼玉県  熊谷  40.9    2007-08-16
# >>>岐阜県  多治見   40.9    2007-08-16
# >>>山形県  山形  40.8    1933-07-25
# >>>山梨県  甲府  40.7    2013-08-10
# >>>和歌山県   かつらぎ    40.6    1994-08-08
# >>>静岡県  天竜  40.6    1994-08-04
# >>>山梨県  勝沼  40.5    2013-08-10
# >>>埼玉県  越谷  40.4    2007-08-16
# >>>群馬県  館林  40.3    2007-08-16

UNIXコマンドでの確認はこちら。

head -3 hightemp.txt

head hightemp.txt

15. 末尾のN行を出力

自然数Nをコマンドライン引数などの手段で受け取り,入力のうち末尾のN行だけを表示せよ.確認にはtailコマンドを用いよ.

knock015.py
# -*- coding: utf-8 -*-

import sys
import argparse

parser = argparse.ArgumentParser(description='Tail command. Accepts an integer and a file name.')

# 行数
parser.add_argument(
    '-l', '--line',
    type = int,
    dest = 'line',
    default = 10,
    help = 'tailコマンドで指定する行数に相当'
)

# ファイル名
parser.add_argument(
    '-f', '--filename',
    type = str,                     # 受け取る値の型を指定する
    dest = 'filename',              # 保存先変数名
    required = True,                # 必須項目
    help = '入力として与えるファイル名'    # --help時に表示する文
)

args = parser.parse_args()
N = args.line
filename = args.filename

# 最後のN行を表示する
f = open(filename)
lines = f.readlines()
M = len(lines)

for i, line in enumerate(lines):
    if i+N >= M:
        #print i
        print line.strip()

f.close()

基本的には、14.から最後の処理を少し変えただけです。
UNIXコマンドでの確認はこちら。

tail -3 hightemp.txt

tail hightemp.txt
4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4