見出し画像

言語処理100本ノックから自然言語処理を始める 第2章

はじめに

最近、様々な事が重なりモチベーションを失いかけていたので新しい事を始めようと思い前から興味のあった自然言語処理を初めて見ることにした。日記みたいな感じで学んだことや工夫すべき事などをメモって行こうと思う。
第一章の反省を踏まえ、1問ずつ模範と照らし合わせていこう思う。
サイトはこちら:https://nlp100.github.io/ja/

環境
・OS: Ubuntu20.04LTS
・Env: Jupyter Lab (Python3.8)

10. 行数のカウント

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

mport pandas as pd
df = pd.read_table('popular-names.txt',header=None, sep='   ')
len(df)

Output: 2780

pandasを使うんだろうなー。でもpandasの記憶がない…
txtをDataFrameにする場合はpd.read_tableでやると。行数はlen()でわかる。
pandasの復習しとかんと。

(base)User@user:~/NLP$ wc -l popular-names.txt

Output: 2780 popular-names.txt

コマンドでの確認、ちゃんと2780が出力されているのでOK。
wcコマンド(word count)は、-cでbyteをカウント、-mで文字数をカウント、-lでライン数をカウント、 -Lで最大widthを、-wでワード数をカウントしてくれる。

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

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

import pandas as pd
df = pd.read_table('popular-names.txt',header=None, sep='	')
df.to_csv('popular-names_space.txt',sep=' ',header=False,index=False)

10と同じく。そしてto_csvを用いてpopular-names_space.txtとして保存。sepを' 'とすれば間をスペースにできる。​
sed,tr,expandコマンドつかった事ない…

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

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

df[0].to_csv('col1.txt',sep=' ',header=False,index=False)
df[1].to_csv('col2.txt',sep=' ',header=False,index=False)

スライシングを用いて1列目を取得、11と同じくto_csvを使い’col1.txt'として保存。2列目も同じく。
df[column:row]のように使える。一行目だけ取り出したい時は、df[:1]で取り出すことができる。

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

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

df1 = pd.read_table('col1.txt',header=None)
df2 = pd.read_table('col2.txt',header=None)
df_merge1 = pd.concat([df1, df2], axis=1)
df_merge1.to_csv('col1_col2.txt',sep='	',header=None,index=False)

データの結合で主に使用するものにはpd.merge、DataFrame.join、pd.concat、 DataFrame.append などがある。今回はconcatを使用。

14. 先頭からN行を出力

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

N = 10
print(df.head(N))

Output: 
          0  1     2     3
0       Mary  F  7065  1880
1       Anna  F  2604  1880
2       Emma  F  2003  1880
3  Elizabeth  F  1939  1880
4     Minnie  F  1746  1880
5   Margaret  F  1578  1880
6        Ida  F  1472  1880
7      Alice  F  1414  1880
8     Bertha  F  1320  1880
9      Sarah  F  1288  1880

df.head(N)で先頭N行目までの表示ができる。

15. 末尾のN行を出力

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

N = 10
print(df.head(N))

Output: 
          0  1     2     3
0       Mary  F  7065  1880
1       Anna  F  2604  1880
2       Emma  F  2003  1880
3  Elizabeth  F  1939  1880
4     Minnie  F  1746  1880
5   Margaret  F  1578  1880
6        Ida  F  1472  1880
7      Alice  F  1414  1880
8     Bertha  F  1320  1880
9      Sarah  F  1288  1880

14同様にtailはその逆。

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

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

N = 3
step = (len(df) // N)
for n in range(N):
   df_split = df.iloc[n*step:(n+1)*step]
   df_split.to_csv('popular-names'+str(n)+'.txt', sep=' ',header=False, index=False)

ilocを用いて分割。iloc[start:end]で指定できる’。

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

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

name = df[0].unique() #use unique for set
name.sort() #sort the df
print(name)

Output: 

['Abigail' 'Aiden' 'Alexander' 'Alexis' 'Alice' 'Amanda' 'Amelia' 'Amy'
'Andrew' 'Angela' 'Anna' 'Annie' 'Anthony' 'Ashley' 'Austin' 'Ava'
'Barbara' 'Benjamin' 'Bertha' 'Bessie' 'Betty' 'Brandon' 'Brian'
'Brittany' 'Carol' 'Carolyn' 'Charles' 'Charlotte' 'Chloe' 'Christopher'
'Clara' 'Crystal' 'Cynthia' 'Daniel' 'David' 'Deborah' 'Debra' 'Donald'
'Donna' 'Doris' 'Dorothy' 'Edward' 'Elijah' 'Elizabeth' 'Emily' 'Emma'
'Ethan' 'Ethel' 'Evelyn' 'Florence' 'Frances' 'Frank' 'Gary' 'George'
'Hannah' 'Harper' 'Harry' 'Heather' 'Helen' 'Henry' 'Ida' 'Isabella'
'Jacob' 'James' 'Jason' 'Jayden' 'Jeffrey' 'Jennifer' 'Jessica' 'Joan'
'John' 'Joseph' 'Joshua' 'Judith' 'Julie' 'Justin' 'Karen' 'Kathleen'
'Kelly' 'Kimberly' 'Larry' 'Laura' 'Lauren' 'Liam' 'Lillian' 'Linda'
'Lisa' 'Logan' 'Lori' 'Lucas' 'Madison' 'Margaret' 'Marie' 'Mark' 'Mary'
'Mason' 'Matthew' 'Megan' 'Melissa' 'Mia' 'Michael' 'Michelle' 'Mildred'
'Minnie' 'Nancy' 'Nicholas' 'Nicole' 'Noah' 'Oliver' 'Olivia' 'Pamela'
'Patricia' 'Rachel' 'Rebecca' 'Richard' 'Robert' 'Ronald' 'Ruth'
'Samantha' 'Sandra' 'Sarah' 'Scott' 'Sharon' 'Shirley' 'Sophia'
'Stephanie' 'Steven' 'Susan' 'Tammy' 'Taylor' 'Thomas' 'Tracy' 'Tyler'
'Virginia' 'Walter' 'William']

unique()を使うことで集合を求めることができる。

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

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

num = df.sort_values(by=2,ascending=False)
print(num)

Output: 
           0  1      2     3
1340    Linda  F  99689  1947
1360    Linda  F  96211  1948
1350    James  M  94757  1947
1550  Michael  M  92704  1957
1351   Robert  M  91640  1947
...       ... ..    ...   ...
27      Annie  F   1326  1881
28     Bertha  F   1324  1881
8      Bertha  F   1320  1880
29      Alice  F   1308  1881
9       Sarah  F   1288  1880

sort_valueでsortできる今回は3コラム目の降順なのでascendingをFalseに設定。

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

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

print(df[0].value_counts())

Output: 

James      118
William    111
John       108
Robert     108
Mary        92
         ... 
Rachel       1
Lucas        1
Scott        1
Kelly        1
Crystal      1
Name: 0, Length: 136, dtype: int64

出現頻度はvalue_counts()で求めることができる。デフォルトで高い順に表示されるので、sortする必要なし。

最後に

以前に東大の松尾研が主催する講義でpandasは一通りやったので、今回はそこまで難しくはなかった。ただ、忘れている箇所が何個かあったのでちゃんと復習しようと思う。次回は、第3章: 正規表現。むずそう。


この記事が気に入ったらサポートをしてみませんか?