LoginSignup
1
4

More than 5 years have passed since last update.

言語処理100本ノック 第2章 UNIXコマンドの基礎

Posted at

はじめに

自然言語処理を基礎からやり直そうと思い、言語処理100本ノック(http://www.cl.ecei.tohoku.ac.jp/nlp100/ )に取り組み始めました。言語処理100本ノックは、東北大学の乾・岡崎研究室(http://www.cl.ecei.tohoku.ac.jp/ )の岡崎先生が提供されている自然言語処理の練習問題集です。

今回は、その第2章に取り組みました。UNIXコマンドでの検証に関しては省略します。

動作環境

Ubuntu 16.04 LTS
Python 3.6.2
Jupyter notebook

No.10 行数のカウント

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

with open('hightemp.txt', 'r', encoding='utf-8') as f :
    print(len(f.readlines()))
24

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

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

with open('hightemp.txt', 'r', encoding='utf-8') as f :
    print(f.read().replace('\t',' '))
高知県 江川崎 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
群馬県 上里見 40.3 1998-07-04
愛知県 愛西 40.3 1994-08-05
千葉県 牛久 40.2 2004-07-20
静岡県 佐久間 40.2 2001-07-24
愛媛県 宇和島 40.2 1927-07-22
山形県 酒田 40.1 1978-08-03
岐阜県 美濃 40 2007-08-16
群馬県 前橋 40 2001-07-24
千葉県 茂原 39.9 2013-08-11
埼玉県 鳩山 39.9 1997-07-05
大阪府 豊中 39.9 1994-08-08
山梨県 大月 39.9 1990-07-19
山形県 鶴岡 39.9 1978-08-03
愛知県 名古屋 39.9 1942-08-02

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

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

with open('hightemp.txt', 'r', encoding='utf-8') as original, \
    open('col1.txt', 'w', encoding='utf-8') as col1, \
    open('col2.txt', 'w', encoding='utf-8') as col2:

    for row in original.readlines() : 
        row_split = row.split('\t')
        col1.write(row_split[0] + '\n')
        col2.write(row_split[1] + '\n')

pandas版

from IPython.display import display
import pandas as pd

input_data = pd.read_csv('hightemp.txt',sep='\t',header=None)
input_data.columns = ['Prefacture', 'City', 'Temperature', 'Date']

input_data['Prefacture'].to_csv('col1.txt', encoding='utf-8',index=False)
input_data['City'].to_csv('col2.txt', encoding='utf-8',index=False)

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

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

with open('col1.txt', 'r', encoding='utf-8') as col1, \
    open('col2.txt', 'r', encoding='utf-8') as col2, \
    open('merged.txt', 'w', encoding='utf-8') as merged:

    for row1, row2 in zip(col1.readlines(), col2.readlines()) :
        merged.write(row1.rstrip() + '\t' +  row2)

pandas版

import pandas as pd

col1 = pd.read_csv('col1.txt', header=None)
col2 = pd.read_csv('col2.txt', header=None)

merged = pd.concat([col1, col2], axis=1)
merged.columns = ['Prefacture', 'City']

merged.to_csv('merged.tsv', sep='\t',header=None ,index=False, encoding='utf-8')

No.14 先頭からN行を出力

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

print('自然数をひとつ入力してください。N = ', end='')
input_num = input()
input_num = int(input_num)

with open('hightemp.txt', encoding='utf-8') as input_data :
    lines = input_data.readlines()

for line in lines[ : input_num] :
    print(line, end='')
自然数をひとつ入力してください。N = 4
高知県   江川崎   41  2013-08-12
埼玉県   熊谷  40.9    2007-08-16
岐阜県   多治見   40.9    2007-08-16
山形県   山形  40.8    1933-07-25

pandas版

from IPython.display import display
import pandas as pd

print('自然数をひとつ入力してください。N = ', end='')
input_num = input()
input_num = int(input_num)

display(pd.read_csv('hightemp.txt', sep='\t').head(input_num))
自然数をひとつ入力してください。N = 4
高知県 江川崎 41 2013-08-12
0 埼玉県 熊谷 40.9 2007-08-16
1 岐阜県 多治見 40.9 2007-08-16
2 山形県 山形 40.8 1933-07-25
3 山梨県 甲府 40.7 2013-08-10

No.15 末尾のN行を出力

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

print('自然数をひとつ入力してください。N = ', end='')
input_num = input()
input_num = int(input_num)

with open('hightemp.txt', encoding='utf-8') as input_data :
    lines = input_data.readlines()

for line in lines[-input_num : ] :
    print(line, end='')
自然数をひとつ入力してください。N = 4
大阪府   豊中  39.9    1994-08-08
山梨県   大月  39.9    1990-07-19
山形県   鶴岡  39.9    1978-08-03
愛知県   名古屋   39.9    1942-08-02

pandas版

from IPython.display import display
import pandas as pd

print('自然数をひとつ入力してください。N = ', end='')
input_num = input()
input_num = int(input_num)

display(pd.read_csv('hightemp.txt', sep='\t').tail(input_num))
自然数をひとつ入力してください。N = 4
高知県 江川崎 41 2013-08-12
19 大阪府 豊中 39.9 1994-08-08
20 山梨県 大月 39.9 1990-07-19
21 山形県 鶴岡 39.9 1978-08-03
22 愛知県 名古屋 39.9 1942-08-02

No.16 ファイルをN分割する

自然数Nをコマンドライン引数などの手段で受け取り,入力のファイルを行単位でN分割せよ.同様の処理をsplitコマンドで実現せよ.

print('自然数をひとつ入力してください。N = ', end='')
input_num = input()
input_num = int(input_num)

with open('hightemp.txt', encoding='utf-8') as input_data :
    lines = input_data.readlines()
    lines_size = len(lines)

    unit_size = lines_size // input_num
    res = lines_size % input_num

    indeces = [0]
    for i in range(1, input_num) : 
        indeces.append(indeces[-1] + unit_size)
        if res > 0 :
            indeces[-1] += 1
            res -= 1
    indeces.append(lines_size)

for i in range(len(indeces) - 1) :
    with open('hightemp_split_' + str(i) + '.txt', 'w', encoding='utf-8') as output_data :
        output_data.writelines(lines[indeces[i] : indeces[i + 1]])
自然数をひとつ入力してください。N = 7

pandas版

import pandas as pd

print('自然数をひとつ入力してください。N = ', end='')
input_num = input()
input_num = int(input_num)

with open('hightemp.txt', encoding='utf-8') as input_data :
    lines = input_data.readlines()
    lines_size = len(lines)

    unit_size = lines_size // input_num
    res = lines_size % input_num

    indeces = [0]
    for i in range(1, input_num) : 
        indeces.append(indeces[-1] + unit_size)
        if res > 0 :
            indeces[-1] += 1
            res -= 1
    indeces.append(lines_size)


自然数をひとつ入力してください。N = 7

No.17 1列目の文字列の異なり

1列目の文字列の種類(異なる文字列の集合)を求めよ.確認にはsort, uniqコマンドを用いよ.

import pandas as pd

input_data = pd.read_csv('hightemp.txt',sep='\t',header=None)
prefacture = input_data.iloc[:,0]
print('異なる文字列数は、{}'.format(len(prefacture.unique())))
異なる文字列数は、12

No.18 各行を3コラム目の数値の降順にソート

各行を3コラム目の数値の逆順で整列せよ(注意: 各行の内容は変更せずに並び替えよ).確認にはsortコマンドを用いよ(この問題はコマンドで実行した時の結果と合わなくてもよい).

from IPython.display import display
import pandas as pd

input_data = pd.read_csv('hightemp.txt',sep='\t',header=None)
input_data.columns = ['Prefacture', 'City', 'Temperature', 'Date']
output_data = input_data.sort_values(by='Temperature', ascending=False)

output_data.index = range(len(output_data))
display(output_data)
Prefacture City Temperature Date
0 高知県 江川崎 41.0 2013-08-12
1 岐阜県 多治見 40.9 2007-08-16
2 埼玉県 熊谷 40.9 2007-08-16
3 山形県 山形 40.8 1933-07-25
4 山梨県 甲府 40.7 2013-08-10
5 和歌山県 かつらぎ 40.6 1994-08-08
6 静岡県 天竜 40.6 1994-08-04
7 山梨県 勝沼 40.5 2013-08-10
8 埼玉県 越谷 40.4 2007-08-16
9 群馬県 館林 40.3 2007-08-16
10 群馬県 上里見 40.3 1998-07-04
11 愛知県 愛西 40.3 1994-08-05
12 愛媛県 宇和島 40.2 1927-07-22
13 千葉県 牛久 40.2 2004-07-20
14 静岡県 佐久間 40.2 2001-07-24
15 山形県 酒田 40.1 1978-08-03
16 岐阜県 美濃 40.0 2007-08-16
17 群馬県 前橋 40.0 2001-07-24
18 千葉県 茂原 39.9 2013-08-11
19 埼玉県 鳩山 39.9 1997-07-05
20 大阪府 豊中 39.9 1994-08-08
21 山梨県 大月 39.9 1990-07-19
22 山形県 鶴岡 39.9 1978-08-03
23 愛知県 名古屋 39.9 1942-08-02

No,19 各行の1コラム目の文字列の出現頻度を求め,出現頻度の高い順に並べる

各行の1列目の文字列の出現頻度を求め,その高い順に並べて表示せよ.確認にはcut, uniq, sortコマンドを用いよ.

from IPython.display import display
import pandas as pd

input_data = pd.read_csv('hightemp.txt',sep='\t',header=None)
input_data.columns = ['Prefacture', 'City', 'Temperature', 'Date']
input_data['Prefacture'].value_counts()
山梨県     3
埼玉県     3
群馬県     3
山形県     3
愛知県     2
静岡県     2
千葉県     2
岐阜県     2
和歌山県    1
高知県     1
愛媛県     1
大阪府     1
Name: Prefacture, dtype: int64

おわりに

後半の問題は、pandasを使った方が便利だという印象でした。
間違いを見つけられた方は、ご指摘いただけると幸いです。

1
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
1
4