2021年2月14日日曜日

random - python

■インポート


import random

■ランダムな値を取得


・実数

#0以上1未満
random.random()

#n以上m以下
random.uniform(n, m)

・整数

#0以上n未満
random.randrange(n)

#n以上m未満
random.randrange(n, m)

#n以上m未満(i間隔)
random.randrange(n, m, i)

#n以上m以下
random.randint(n, m)

・リストからランダムに値を取得

random.choice(['a', 'b', 'c'])

・リストをシャッフル

lsA = ['a', 'b', 'c']

random.shuffle(lsA)
print(lsA)

#出力
# ['b', 'a', 'c']

2021年2月5日金曜日

結合 - pandas - python

■インポート


import pandas as pd
 以降の呼び出し簡略化のため「pd」と名前を付ける

■テーブル作成


df1 = pd.DataFrame({'列名1':[111,222,333],'列名2':['aaa','bbb','ccc'],'列名3':['a',2,'あ']})
df2 = pd.DataFrame({'列名1':['xxx','yyy','zzz'],'列名2':['aaa','ccc','a'],'列名3':['b','あ',3]})

print(df1)
print(df2)

#出力
#    列名1  列名2 列名3
# 0  111  aaa   a
# 1  222  bbb   2
# 2  333  ccc   あ
#
#    列名1  列名2 列名3
# 0  xxx  aaa   b
# 1  yyy  ccc   あ
# 2  zzz    a   3

■結合


・横に結合

df = pd.merge(df1, df2, on='列名2')
print(df)

#出力
#    列名1_x  列名2 列名3_x 列名1_y 列名3_y
# 0    111  aaa     a   xxx     b
# 1    333  ccc     あ   yyy     あ
pd.merge()の第一引数(left)、第二引数(right)にデータフレームを指定
on=で値を比較する列を指定
 デフォルトではinner join(値が等しい行のみ残す)となる
 on=で指定した同名の列はまとめられ
 他の列名が重複していると列名に語尾が追加される

df = pd.merge(df1, df2, left_on='列名3', right_on='列名2')
print(df)

#出力
#    列名1_x 列名2_x 列名3_x 列名1_y 列名2_y 列名3_y
# 0    111   aaa     a   zzz     a     3
 違う列名同士を当てる場合はleft_onright_onでそれぞれ指定

df = pd.merge(df1, df2, on=['列名2','列名3'])
print(df)

#出力
#    列名1_x  列名2 列名3 列名1_y
# 0    333  ccc   あ   yyy
 複数の列を当てる場合はリストで指定

#left join
df = pd.merge(df1, df2, on='列名2', how='left')
print(df)

#right join
df = pd.merge(df1, df2, on='列名2', how='right')
print(df)

#outer join
df = pd.merge(df1, df2, on='列名2', how='outer')
print(df)

#出力
#    列名1_x  列名2 列名3_x 列名1_y 列名3_y
# 0    111  aaa     a   xxx     b
# 1    222  bbb     2   NaN   NaN
# 2    333  ccc     あ   yyy     あ
#
#    列名1_x  列名2 列名3_x 列名1_y 列名3_y
# 0  111.0  aaa     a   xxx     b
# 1  333.0  ccc     あ   yyy     あ
# 2    NaN    a   NaN   zzz     3
#
#    列名1_x  列名2 列名3_x 列名1_y 列名3_y
# 0  111.0  aaa     a   xxx     b
# 1  222.0  bbb     2   NaN   NaN
# 2  333.0  ccc     あ   yyy     あ
# 3    NaN    a   NaN   zzz     3
how=で結合方法を指定できる
 当たらない行の値はNaNになる

#cross join
df = pd.merge(df1, df2, how='cross')

print(df)

#出力
#    列名1_x 列名2_x 列名3_x 列名1_y 列名2_y 列名3_y
# 0    111   aaa     a   xxx   aaa     b
# 1    111   aaa     a   yyy   ccc     あ
# 2    111   aaa     a   zzz     a     3
# 3    222   bbb     2   xxx   aaa     b
# 4    222   bbb     2   yyy   ccc     あ
# 5    222   bbb     2   zzz     a     3
# 6    333   ccc     あ   xxx   aaa     b
# 7    333   ccc     あ   yyy   ccc     あ
# 8    333   ccc     あ   zzz     a     3
pandas ver1.2.0からcross joinが追加

・縦に結合

#df2に列を追加
df2['列名4'] = 'd'

df = pd.concat( [df1, df2] )
print(df)

#出力
#    列名1  列名2 列名3  列名4
# 0  111  aaa   a  NaN
# 1  222  bbb   2  NaN
# 2  333  ccc   あ  NaN
# 0  xxx  aaa   b    d
# 1  yyy  ccc   あ    d
# 2  zzz    a   3    d
pd.concat()に結合するデータフレームをリストで指定
 同じ列名が結合される
 違う列名がある場合、値がNaNで補完される
 インデックスは元の値を引き継ぐ

#df2に列を追加
df2['列名4'] = 'd'

df = pd.concat( [df1, df2], join='inner', ignore_index=True)
print(df)

#出力
#    列名1  列名2 列名3
# 0  111  aaa   a
# 1  222  bbb   2
# 2  333  ccc   あ
# 3  xxx  aaa   b
# 4  yyy  ccc   あ
# 5  zzz    a   3
join='inner'とすると列名が等しいものだけ残す
ignore_index='True'とするとインデックスがリセットされる

行操作 - pandas - python

■インポート


import pandas as pd
 以降の呼び出し簡略化のため「pd」と名前を付ける

■テーブル作成


df = pd.DataFrame({'列名1':[111,222,333],'列名2':['aaa','bbb','ccc'],'列名3':['a',2,'あ']})
print(df)

#出力
#    列名1 列名2 列名3
# 0    111   aaa     a
# 1    222   bbb     2
# 2    333   ccc     あ

■行操作


・1行だけ抜き出す

row = df.loc[1]
print(row)

print(row['列名2'])

#出力
# 列名1    222
# 列名2    bbb
# 列名3      2
# Name: 1, dtype: object
#
# bbb
.loc[]にインデックス名を指定
 シリーズの行版のようなもの
 さらに[ ]で列名を指定して値を抜き出せる

row = df.iloc[2]
print(row)

#出力
# 列名1    333
# 列名2    ccc
# 列名3      あ
# Name: 2, dtype: object
.iloc[]に行数(0始まり)を指定しても同様
 ※この例ではインデックスと行数が等しいのでわかりにくい

・行の値を変更する

df.loc[0] = [444,'ddd','い']
print(df)

#出力
#    列名1  列名2 列名3
# 0  444  ddd   い
# 1  222  bbb   2
# 2  333  ccc   あ
.loc[]にリストを代入
 ※リストのサイズは列数に合わせる

・インデックスを変更する

df.index = ['x','y','z']
print(df)

#出力
#    列名1  列名2 列名3
# x  111  aaa   a
# y  222  bbb   2
# z  333  ccc   あ
 df.indexにリストを代入
 ※リストのサイズは行数に合わせる

df.index= ['x','y','z']
print(df)

df = df.reset_index()
print(df)

#出力
#    列名1  列名2 列名3
# x  111  aaa   a
# y  222  bbb   2
# z  333  ccc   あ
#
#   index  列名1  列名2 列名3
# 0     x  111  aaa   a
# 1     y  222  bbb   2
# 2     z  333  ccc   あ
.reset_index()でインデックスを通し番号で振り直せる
 前のインデックスは列として追加される
.reset_index(drop=True)とすると前のインデックスは残らない

・フィルター

df = df[ df['列名1']>200 ]
print(df)

#出力
#    列名1  列名2 列名3
# 1  222  bbb   2
# 2  333  ccc   あ
[ ]にフィルター条件を記載
 列はシリーズで指定

df = df[ (df['列名1']>200)&(df['列名3']=='あ') ]
print(df)

#出力
#    列名1  列名2 列名3
# 2  333  ccc   あ
 複数条件は「&(and条件)」か「|(or条件)」を使用

■参考


・フィルターについて詳しく

 データフレームをフィルターするには
df[ ]値がTrueかFalseのリストを指定する
df = df[ [False, True, False] ]
print(df)

#出力
#    列名1  列名2 列名3
# 1  222  bbb   2
 リストは残したい行をTrueとし、行数と同じサイズにする

print(df['列名1']>200)

#出力
# 0    False
# 1     True
# 2     True
# Name: 列名1, dtype: bool
 実際に条件部分だけ見ると、TrueかFalseのリストとなっている

2021年2月3日水曜日

列操作 - pandas -python

■インポート


import pandas as pd
 以降の呼び出し簡略化のため「pd」と名前を付ける

■テーブル作成


df = pd.DataFrame({'列名1':[111,222,333],'列名2':['aaa','bbb','ccc'],'列名3':['a',2,'あ']})
print(df)

#出力
#    列名1 列名2 列名3
# 0    111   aaa     a
# 1    222   bbb     2
# 2    333   ccc     あ

■列操作


・列を抜き出す

df = df[ ['列名2','列名3'] ]
print(df)

#出力
#    列名2 列名3
# 0  aaa   a
# 1  bbb   2
# 2  ccc   あ
[ ]に列名のリストを指定
 列は指定した順になるので並べ替えにも使える

df = df[ ['列名2'] ]
print(type(df))

df = df['列名2']
print(type(df))

#出力
# <class 'pandas.core.frame.DataFrame'>
# <class 'pandas.core.series.Series'>
 1列抜き出す場合もリストで指定する
 リストでないとシリーズとして抜き出される

・列を削除する

df = df.drop(['列名2'], axis=1)
print(df)

#出力
#    列名1 列名3
# 0  111   a
# 1  222   2
# 2  333   あ
.drop()の第一引数に削除したい列名のリスト
 第二引数にaxis=1を指定(デフォルト(axis=0)だと行の削除になる)
 ※1列だけ削除する場合はリストでなくても可

・列を追加する

df['列名4'] = ['b','3','い']
print(df)

#出力
#    列名1  列名2 列名3 列名4
# 0  111  aaa   a   b
# 1  222  bbb   2   3
# 2  333  ccc   あ   い
[ ]で追加したい列名を指定
 そこに値のリストを代入する
 ※リストのサイズは行数と合わせる

df['列名4'] = 'd'
print(df)

#出力
#    列名1  列名2 列名3 列名4
# 0  111  aaa   a   d
# 1  222  bbb   2   d
# 2  333  ccc   あ   d
 値だけ指定した場合は全行で同じ値となる

df['列名4'] = df['列名1'] * 3
print(df)

#出力
#    列名1  列名2 列名3  列名4
# 0  111  aaa   a  333
# 1  222  bbb   2  666
# 2  333  ccc   あ  999
 元の列を使い演算することも可能

・列の値を変更する

df['列名3'] = [444, 555, 666]
print(df)

#出力
#    列名1  列名2  列名3
# 0  111  aaa  444
# 1  222  bbb  555
# 2  333  ccc  666
[ ]で変更したい列名を指定
 そこに値のリストを代入する

df['列名3'] = df['列名1'] * 3
print(df)

#出力
#    列名1  列名2  列名3
# 0  111  aaa  333
# 1  222  bbb  666
# 2  333  ccc  999
 元の列を使い演算することも可能

・列名を変更する

df = df.rename(columns={'列名1':'col1','列名3':'col3'})
print(df)

#出力
#    col1  列名2 col3
# 0   111  aaa    a
# 1   222  bbb    2
# 2   333  ccc    あ
.rename()columns=辞書型で指定
 keyが元の列名、valueが変更後の列名
 ※columns=を付けないとインデックスの名前変更になる

df.columns = ['col1','col2','col3']
print(df)

#出力
#    col1 col2 col3
# 0   111  aaa    a
# 1   222  bbb    2
# 2   333  ccc    あ
 全ての列名を変える場合はdf.columnsにリストを代入でも可
 ※リストのサイズは列数に合わせる

ファイル読み込み - pandas - python

■インポート


import pandas as pd
 以降の呼び出し簡略化のため「pd」と名前を付ける

■Excelファイル


・ファイルを指定

df = pd.read_excel('ファイルパス')

print(df)

#出力
#    col1 col2 col3
# 0     1    a    あ
# 1     2    b    い
# 2     3    c    う
 ファイルパスだけ指定すると一番左のシートが読み込まれる
 1行目が列名になり、インデックスは自動で付けられる

・シートを指定

df = pd.read_excel('ファイルパス', sheet_name='シート名')
sheet_name=でシート名を指定

・その他の指定

#読み込み開始行を指定(0始まり)
df = pd.read_excel('ファイルパス', header=1)

#読み込み行数を指定(列名を除く)
df = pd.read_excel('ファイルパス', nrows=2)

#読み込み列を指定
df = pd.read_excel('ファイルパス', usecols=['列名1','列名2',・・・])
header=Noneとすると1行目から値になる
 その場合、列名は自動付与(0,1,2,・・・)

■CSVファイル


・ファイルを指定

df = pd.read_csv('ファイルパス')

print(df)

#出力
#    col1 col2 col3
# 0     1    a    あ
# 1     2    b    い
# 2     3    c    う
.read_csvはデフォルトだとutf-8で読み込む

df = pd.read_csv('ファイルパス', encoding='cp932')
 エラーになる場合はencoding=でファイルに合った文字コードを指定
 ※cp932shift-jisと同じ

・その他の指定

#読み込み開始行を指定(0始まり)
df = pd.read_csv('ファイルパス', header=1)

#読み込み行数を指定(列名を除く)
df = pd.read_csv('ファイルパス', nrows=2)

#読み込み列を指定
df = pd.read_csv('ファイルパス', usecols=['列名1','列名2',・・・])

#型を指定(列全てに適応)
df = pd.read_csv('ファイルパス', dtype=str)

#区切り文字を指定
df = pd.read_csv('ファイルパス', sep='\t')
sep=で区切り文字を変更できる(デフォルトはカンマ(,))
TSVファイルの場合はsep='\t'と指定

2021年2月1日月曜日

データフレーム - pandas - python

■インポート


import pandas as pd
 以降の呼び出し簡略化のため「pd」と名前を付ける

■データフレーム


・データフレーム作成

df = pd.DataFrame({'列名1':[111,222,333],'列名2':['aaa','bbb','ccc'],'列名3':['a',2,'あ']})
print(df)

#出力
#    列名1 列名2 列名3
# 0    111   aaa     a
# 1    222   bbb     2
# 2    333   ccc     あ
.DataFrame()に辞書型で構成を指定
 keyに列名、valueに列の値をリストで指定
 ※リストのサイズは全て同じにする

・データフレームの構造

df = pd.DataFrame({'列名1':[111,222,333],'列名2':['aaa','bbb','ccc'],'列名3':['a',2,'あ']})

print(df.columns)
print(list(df.columns))

print(df.index)
print(list(df.index))

#出力
# Index(['列名1', '列名2', '列名3'], dtype='object')
# ['列名1', '列名2', '列名3']
#
# RangeIndex(start=0, stop=3, step=1)
# [0, 1, 2]
 データフレームとは列に列名、行にインデックスが付けられたテーブル
 インデックスはデータフレーム作成時に自動で付与される
 それぞれ.columns.indexで取得できる(リストに直すと見やすい)

 データフレームはシリーズという単位に分解できる
df = pd.DataFrame({'列名1':[111,222,333],'列名2':['aaa','bbb','ccc'],'列名3':['a',2,'あ']})

print(df['列名1'])

print(df['列名1'][1])

#出力
# 0    111
# 1    222
# 2    333
# Name: 列名1, dtype: int64
#
# 222
 シリーズは列を1つ抜き出したようなもの
名前(列名)インデックスを持つ
 dfに[ ]で列名を指定して取得
 さらに[ ]でインデックスを指定すると値を取得できる


pandas - python

■インストール


 コマンドプロンプトから実行
pip install pandas

■データフレーム操作

データフレーム

ファイル読み込み

列操作

行操作

結合