[[Pythonバイオ]] ~
&counter();   &lastmod();~

*pandasティップス [#gfafdcc8]

**行選択と列選択 [#s06c1b34]
***行位置選択 [#ocd73bc9]

***行の値選択、列の値選択 [#c8f0f893]

**セル選択 [#l2d0b6fa]

**行演算と列演算 [#g8a09294]

**2列間での演算 [#b2cbdb07]
[[Pandasで複数の列を値をもとに、新しい列を任意の関数で定義する方法 | Shikoan's ML Blog:https://blog.shikoan.com/pandas-newcolumn-lambda/]]

 import pandas as pd
 comike = pd.DataFrame({
     "block" : ["AX", "AY", "あZ", "あX", "イQ", "イR"],
     "number" : [1, 1, 10, 11, 12, 13],
     "side" : ["aX", "bX", "aY", "bZ", "aQ", "bR"]
 })
 print(comike)
 #comike["space"] = comike.apply(lambda x: f"{x['block']}-{x['number']:02d}{x['side']}", axis=1)
 comike = comike[comike.apply(lambda x: x['block'][1]==x['side'][1], axis=1) ]
 print(comike)

**値・行名/列名でソートする [#n7f98c79]
[[pandas.DataFrame, Seriesをソートするsort_values, sort_index | note.nkmk.me:https://note.nkmk.me/python-pandas-sort-values-sort-index/]]

値でソートする
 df.sort_values()
 df.sort_values(ascending=False)
行名でソートする
 df.sort_index()
列名でソートする
 df.sort_index(axis=1)


**ifのある内包 [#nc7b9210]
 even_list = [i for i in range(10) if i % 2 == 0]

 even_list = [i if i % 2 == 0 else "odd" for i in range(10)]

**三項演算子(条件式) [#b032fe2b]
[[Pythonの三項演算子(条件演算子)でif文を一行で書く | note.nkmk.me:https://note.nkmk.me/python-if-conditional-expressions/]]~
[[6. 式 (expression) — Python 3.8.0 ドキュメント 6.12. 条件式 (Conditional Expressions):https://docs.python.org/ja/3/reference/expressions.html#conditional-expressions]]
 result = a * 2 if a % 2 == 0 else a * 3

elifを含めたい時(推奨せず)
 result = 'negative' if a < 0 else 'positive' if a > 0 else 'zero'

**要素データの置き換え replace [#h8fdf3a7]
[[pandas.DataFrame, Seriesの要素の値を置換するreplace | note.nkmk.me:https://note.nkmk.me/python-pandas-replace/]]
 df = df.replace(oldvalue, newvalue)

**列名の付け替え rename [#bbba1027]
[[pandas.DataFrameの行名・列名の変更 | note.nkmk.me:https://note.nkmk.me/python-pandas-dataframe-rename/]]
 df = df.rename(columns={旧名: 新名, 旧名2: 新名2, ...})

なお、indexに対する名前を付けるには
 df.index.name = colname1
同様に、
 df.columns.name = colname2
つまり
 import pandas as pd
 df = pd.DataFrame([[1,2,3],[4,5,6],[7,8,9]], columns=['A','B','C'])
 print(df)
 df.index.name='インデックス'
 print(df)
 df.columns.name = 'カラム'
 print(df)
とすると、何もつけないときは
    A  B  C
 0  1  2  3
 1  4  5  6
 2  7  8  9
indexに名前'インデックス'を付けると
         A  B  C
 インデックス         
 0       1  2  3
 1       4  5  6
 2       7  8  9
更に、columnに名前'カラム'を付けると
 カラム     A  B  C
 インデックス         
 0       1  2  3
 1       4  5  6
 2       7  8  9
となる。

**インデックスの付け替え  drop_indexとset_index [#b993a345]
[[pandas.DataFrame, Seriesのインデックスを振り直すreset_index | note.nkmk.me
https://note.nkmk.me/python-pandas-reset-index/]]
 df = df.drop_index()  # インデックスは新たに列として加えられる。もし列名が重複するとエラー

 df = df.drop_index(drop=True)  # インデックスを完全に削除(列として残さない)

 df = df.set_index('列名')  # 列名の列をインデックスとして使う。その列は消える

 df = df.reset_index.set_index('列名') # 元のインデックスを列として残しつつ変更

**列位置の入れ替え [#ffcfd8c3]
 df = df.loc[:, ["col3", "col1", "col2", "col0"]]

**行・列のdrop [#z8e03439]
[[pandas.DataFrameの行・列を指定して削除するdrop | note.nkmk.me:https://note.nkmk.me/python-pandas-drop/]]
 df = df.drop('行名', axis=0)   # axis=0はデフォルト
 df = df.drop(index='行名')
 df = df.drop('列名', axis=1)
 df = df.drop(column='行名')
複数行・列の場合
 df = df.drop(index=['行名1', '行名2']

行番号で指定
 df = df.drop(index=df.index[1, 3, 5]))

なお、値を条件にして行を削除/残すのは、
 df = df[df['参照']>=3]
 df = df[(df['参照1']>=3) and (df['参照2']!='')]
でできる。

**列名が重複してしまった時の列の削除 [#bf69d059]
 import pandas as pd
 df = pd.DataFrame([['A',1, 0.1], ['B', 2, 0.2], ['C', 3, 0.3], ['D', 4, 0.4]], 
 columns=['ラベル', '値', '値'])
 print(df)
 #  ラベル  値    値
 #0   A  1  0.1
 #1   B  2  0.2
 #2   C  3  0.3
 #3   D  4  0.4
 
 dfx = df[['ラベル', '値']]    # 値は2つ残る
 print(dfx)
 #  ラベル  値    値
 #0   A  1  0.1
 #1   B  2  0.2
 #2   C  3  0.3
 #3   D  4  0.4
 
 dfx = df.drop('値', axis=1)   # 2つともdropする
 print(dfx)
 #  ラベル
 #0   A
 #1   B
 #2   C
 #3   D
 
 dfx = df.drop(df.columns[[2]], axis=1)  # 位置2を指定しても2つともdropする
 print(dfx)
 #  ラベル
 #0   A
 #1   B
 #2   C
 #3   D
 
 dfx = df.copy()   # 浅いコピーだと列名書換えはdfの方にも及ぶので注意
 dfx.columns = ['ラベル', '値', '値2']   # すべて指定すれば列名はすべて書き変えられる
 dfx = dfx[['ラベル', '値']]   # 値2をdropすればいい
 print(dfx)
 #  ラベル  値
 #0   A  1
 #1   B  2
 #2   C  3
 #3   D  4
 
 dfx = df.rename(columns={'値': '値3'})  # 両方とも書き換えられる
 print(dfx)
 #  ラベル  値3   値3   <-- 両方とも'値3'になるのでダメ
 #0   A   1  0.1
 #1   B   2  0.2
 #2   C   3  0.3
 #3   D   4  0.4

結論として、列名を全面的に書換えするしかなさそうだ。

**DataFrameから辞書 [#n9c1c571]
[[pandas.DataFrame, Seriesを辞書に変換(to_dict) | note.nkmk.me:https://note.nkmk.me/python-pandas-to-dict/]]

DataFrameの2つの列の間の関係を辞書にするためには、
-キー側の列の値をindexとし、
-値を(列値として)並べた
-Seriesを作る
そのSeriesを、ser.to_dict() で辞書型に変換する

**Series/DataFrameからリストに変換するなら .values.tolist() [#zff41b08]
[[pandas.DataFrame, SeriesとPython標準のリストを相互に変換 | note.nkmk.me:https://note.nkmk.me/python-pandas-list/]]

Seriesの値部分だけなら
 s = pd.Series([0, 1, 2])
 l_1d = s.values.tolist()

DataFrameの値部分だけなら
 df = pd.DataFrame([[0, 1, 2], [3, 4, 5]])
 l_2d = df.values.tolist()
 print(l_2d)
 # [[0, 1, 2], [3, 4, 5]]

行ラベル(行名)ともリストに変換するには、結局reset_indexとかでインデックスを列に含める
 l_1d_index = s_index.reset_index().values.tolist()
 print(l_1d_index)
 # [['row1', 0], ['row2', 1], ['row3', 2]]

列ラベル(列名)はreset_indexに相当する機能が無いので、1つの方法として転置してからreset_indexをかける。
 l_2d_index_columns = df_index.reset_index().T.reset_index().T.values.tolist()
 print(l_2d_index_columns)
 # [['index', 'col1', 'col2', 'col3'], ['row1', 0, 1, 2], ['row2', 3, 4, 5]]

ラベルだけなら、df.index、df.columnsだが、リストにするためにtolist()しておく
 df.index.tolist()
 df.columns.tolist()

**重複した行をdropする [#dacc5443]
[[duplicatedとdrop_duplicates:https://note.nkmk.me/python-pandas-duplicated-drop-duplicates/]]
 df = df.duplicated(keep='last', subset=['この列での重複']) # 重複ならTrue、ないならFalseの1列
 df = df[~df.duplicated(keep='...', subset=['..', '..'])]  # 重複以外をひろう(=drop_duplicates)
 
 df = df.drop_duplicates(keep='last')  # 重複した列を最後の1つだけ残して削除

**文字列を含む行の抽出 [#g058fbd0]
[[pandasで特定の文字列を含む行を抽出(完全一致、部分一致) | note.nkmk.me:https://note.nkmk.me/python-pandas-str-contains-match/]]

完全一致は == でよい。
 dfx = df[df['state'] == 'CA']

部分一致は、in はダメらしい。str.contains() を使う。
 dfx = df[df['name'].str.contains('li')

但し、デフォルトでは第1引数を正規表現と解釈する(要するにre.searchと同様)ので、
ピリオド等を含む場合には正しくない。回避するためには regex=False を指定するとよい。
 dfx = df[df['name'].str.contains('li', regex=False)

また、要素が欠損値NaNである場合、デフォルトではNaNを返すので、行を抽出するとエラーになる。オプションとして na=True/False を指定する。
 dfx = df[df['name'].str.contains('li', na=True)]   # NaNは抽出結果に含まれる
 dfx = df[df['name'].str.contains('li', na=True)]   # NaNは抽出結果に含まない

なお、str.containsの他、 str.startswith や str.endswidth 更に str.match(〜re.matchと同様の動作) が使える。

**要素が指定リストに含まれる行の抽出 (文字列ではなくてリスト) [#h6f9b92f]
[[pandas.DataFrameの行を条件で抽出するquery | note.nkmk.me:
https://note.nkmk.me/python-pandas-query/]]

基本的に、isinメソッドを使うか、queryメソッドの中で in を使うか。
 dfx = df[df['state'].isin(['NY', 'TX'])]
か
 dfx = df.query('state in ["NY", "TX"]')
これも可:
 dfx = df.query('state == ["NY", "TX"]'

**Groupby [#u931854d]
[[pandas.DataFrameをGroupByでグルーピングし統計量を算出 | note.nkmk.me:https://note.nkmk.me/python-pandas-groupby-statistics/]]
 grouped = df.groupby('グループ化したい列名')
この結果に対して統計演算ができる
 df = grouped.sum()
使えるのはsum(), mean(), min(), max(), std(), var()など

また、agg()を使って、関数を適用することができる。関数はSeriesを受け取って
objectを返す関数でなければならない。
 df = grouped.agg(lambda x: type(x))['sl'])
 df = grouped.agg(min)
列ごとに異なる関数を適用することも可能。
 df = grouped.agg({'列1': min}, {'列2': max})

複数の列をキーにしてグループ化できる。
 gf = df.groupby(['列1', '列2']).mean()

as_index=Falseを指定すると(True時はキーが結果DFのインデックスになるが)、キーは結果DFの行のままで残りインデックスは元のまま
 df = pd.DataFrame({
     'city': ['osaka', 'osaka', 'osaka', 'osaka', 'tokyo', 'tokyo', 'tokyo'],
     'food': ['apple', 'orange', 'banana', 'banana', 'apple', 'apple', 'banana'],
     'price': [100, 200, 250, 300, 150, 200, 400],
     'quantity': [1, 2, 3, 4, 5, 6, 7]
 })
 
 gb = df.groupby(['city', 'food']).mean()  # as_index指定なし(デフォルトはTrue)
 print(gb)
に対して
                price  quantity
 city  food                   
 osaka apple   100.0       1.0
       banana  275.0       3.5
       orange  200.0       2.0
 tokyo apple   175.0       5.5
       banana  400.0       7.0

だが、as_index=Falseにすると
 gb_noindex = df.groupby(['city', 'food'], as_index=False).mean()
 print(gb_noindex)
に対して
      city    food  price  quantity
 
 0  osaka   apple  100.0       1.0
 1  osaka  banana  275.0       3.5
 2  osaka  orange  200.0       2.0
 3  tokyo   apple  175.0       5.5
 4  tokyo  banana  400.0       7.0

のようにcityとfoodの列が残る。

**Groupbyのグループを取出す [#t7c1b24c]
[[Pandas の groupby の使い方 - Qiita:https://qiita.com/propella/items/a9a32b878c77222630ae]]

df.groupby('city').groups

 {'osaka': Int64Index([0, 1, 2, 3], dtype='int64'),
  'tokyo': Int64Index([4, 5, 6], dtype='int64')}

df.groupby('city').get_group('osaka')

 city	food	price	quantity
 0	osaka	apple	100	1
 1	osaka	orange	200	2
 2	osaka	banana	250	3
 3	osaka	banana	300	4

df.groupby('city').size()

 city
 osaka    4
 tokyo    3
 dtype: int64

df.groupby('city').size()['osaka']
 4

**map, apply [#f837b768]
[[pandasで要素、行、列に関数を適用するmap, applymap, apply | note.nkmk.me:https://note.nkmk.me/python-pandas-map-applymap-apply/]]


**複数dfをjoin [#g92089e4]
[[reference:https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.join.html]]

DFのリスト joinlist = [df1, df2, ..., dfn] を用意し、dfにjoinする。
 dfout = df.join(joinlist)
このとき、キー指定("on"の指定)はできない。インデックスをキーにしてjoinする。

つまり、あらかじめインデックスを付け替えておく必要がある。
 df1 = df1.set_index('column to use as key')

**NaN扱い [#s643db78]
NaNはnumpyのnan

DFでなければ
 if np.isnan(np.nan):
     hogehoge

DFでのnan判定

[[Reference→API reference のgeneral function:https://pandas.pydata.org/pandas-docs/stable/reference/general_functions.html#top-level-missing-data]]にある
 df = pd.DataFrame8{[1,3],[2,np.nan]])
 print(df.isnull())
 print(df.notnull())
なお、isnull()はisna()のalias、notnull()はnotna()のalias


**初めに空のDataFrameを作って後からデータ行を足す [#u5bf5dd4]
 df = pd.DataFrame( columns=['A', 'B'] )
 for u in [0, 1, 2, 3]:
     temp_series = pd.Series( [i, i*i], index=df.columns )
     df = df.append( temp_series, ignore_index=True )


**collections.Counterの結果を加える [#h1f83e12]
[[[Python] リストの要素の数を数える (collections.Counter) | Hibiki Programming Notes:https://hibiki-press.tech/learn_prog/python/collections-counter/3769]]

 c1 = collections.Counter('abbcabbbccca')
 c1.update({'a':1, 'b':1, 'c':1})   # c1を書き換えることに注意('+'と異なる)
または
 c1 = collections.Counter('abbcabbbccca')
 c1.update('abc')
もOK

引く場合は、subtract
 >>> c = Counter(a=4, b=2, c=0, d=-2)
 >>> d = Counter(a=1, b=2, c=3, d=4)
 >>> c.subtract(d)   # cを書き換えることに注意('-'と異なる)
 >>> c
 Counter({'a': 3, 'b': 0, 'c': -3, 'd': -6})
0やマイナスになり得る

また、[[8.3. collections --- コンテナデータ型 &#8212; Python 3.6.10rc1 ドキュメント:https://docs.python.org/ja/3.6/library/collections.html]]では
 >>> c = Counter(a=3, b=1)
 >>> d = Counter(a=1, b=2)
 >>> c + d                       # add two counters together:  c[x] + d[x]
 Counter({'a': 4, 'b': 3})
 >>> c - d                       # subtract (keeping only positive counts)
 Counter({'a': 2})
 >>> c & d                       # intersection:  min(c[x], d[x]) 
 Counter({'a': 1, 'b': 1})
 >>> c | d                       # union:  max(c[x], d[x])
 Counter({'a': 3, 'b': 2})
引き算は0や負になると要素が消える(Countだから?)ので注意〜subtractと振る舞いが異なる。

基本的に、カウントが0の項目は削る方向に動く。従って、Counter同士を足したり引いたり
した結果、値が0になればprintしても見えなくなる。

Counterはほぼ辞書と同じなので、次項のソートが使える。

**辞書のソート [#gc6f2ebd]
[[Pythonの辞書(dict)をソートする方法まとめ | HEADBOOST:https://www.headboost.jp/python-how-to-sort-dict/#21]]
 d = {'b': 2, 'a': 3}
 print(sorted(d)) # keyを取出してソート
 print(sorted(d.keys())) # 上と同じこと
 print(sorted(d.values()))
 print(sorted(d.items())) # itemを取出してkey順でソート
 print(sorted(d.items(), key = lambda x : x[1])) # itemを取出してvalue順でソート

これを使って、codons数を数えて出力をcodon名順にソート
 import pandas as pd
 import collections
 # dict (codon count) をDFに書き込む
 # d = {'B':1, 'C':2}
 # df= pd.DataFrame(columns=['A', 'B', 'C'])
 # 結果としてAは0, Bは1, Cは2と書いて欲しい
 
 zerodic = collections.Counter([])  # これは不可 エントリーCが入らない
 zerodic = collections.Counter({'A':0, 'B':0, 'C':0})
 print(zerodic)  ## 意図は{'A', 0:, 'B': 0, 'C':0}
 d = collections.Counter({'B':1, 'C':2})
 print(zerodic+d)  # これは不可。カウントが0のエントリーCが入らない
 #
 zerodic.update({'B':1, 'C':2})  # updateだと元のzerodicがそのまま型紙になる
               # 但しupdateはin-placeで置き換えるので注意
 print(zerodic)
 # あとはキーでソートして値をリストにして、pd.Seriesに変換して、pd.DataFrameに追加
 szero = sorted(zerodic.items(), key=lambda x: x[0])  # ペアでソート、出力はペアのリスト
 szerolist = [u[1] for u in szero]  # 値だけのリストにする
 print(szerolist)
 ser = pd.Series(szerolist, index=df.columns)
 df = df.append(ser, ignore_index=True)
 print(df)


**read_csvとto_csv [#uc197a4a]
***read_csv [#c3b65411]
[[pandasでcsv/tsvファイル読み込み(read_csv, read_table) | note.nkmk.me:https://note.nkmk.me/python-pandas-read-csv-tsv/]]~
[[pandas.read_csv &#8212; pandas 0.25.0 documentation:https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_csv.html]]~
[[codecs &#8212; Codec registry and base classes &#8212; Python 3.7.4 documentation:https://docs.python.org/3/library/codecs.html#standard-encodings]]

 import pandas as pd
 pd.read_csv('filename', sep='\t', header=0, skiprows=[], encoding='cp932')

または
 with open('filename', 'r', encoding='...') as fin:
     pd.read_csv(fin, ... )

なお、separatorが複数空白を含むとき、
 pd.read_csv('filename', sep='\s+')
が使える。[[python - How to make separator in pandas read_csv more flexible wrt whitespace? - Stack Overflow:https://stackoverflow.com/questions/15026698/how-to-make-separator-in-pandas-read-csv-more-flexible-wrt-whitespace]]

***to_csv [#v2cce651]
 df = ...
 df.to_csv('filename', ...)


**read_excelとto_excel [#of1b91ac]
[[pandas.DataFrame.to_excel &#8212; pandas 0.25.0 documentation:https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.to_excel.html]]

If you wish to write to more than one sheet in the workbook, it is necessary to specify an ExcelWriter object:

 >>> df2 = df1.copy()
 >>> with pd.ExcelWriter('output.xlsx') as writer:  # doctest: +SKIP
 ...     df1.to_excel(writer, sheet_name='Sheet_name_1')
 ...     df2.to_excel(writer, sheet_name='Sheet_name_2')

**to_excelで、セル内に改行を置きたい場合 [#kbbbf58d]
デフォルトでは改行は不可(\nを入れても効果ない)

セルのスタイルプロパティで、wrap_text=Trueを設定する。
-[[Python: How to create multi line cells in excel when exporting a pandas dataframe Stack Overflow:https://stackoverflow.com/questions/50908676/python-how-to-create-multi-line-cells-in-excel-when-exporting-a-pandas-datafram]] StyleFrameは使いたくない?
-[[python - Writing multi-line strings into cells using openpyxl - Stack Overflow:https://stackoverflow.com/questions/15370432/writing-multi-line-strings-into-cells-using-openpyxl]] Excelファイルを作りながら(データを置きながら)改行を入れる感じ。データを入れるところはto_Excelで楽したい。
-[[python - Apply 'wrap_text' to all cells using openpyxl - Stack Overflow:https://stackoverflow.com/questions/42215933/apply-wrap-text-to-all-cells-using-openpyxl/52494457]] これですべてのセルにwrap-textを付けられる。

結局、to_excelでファイルを作ってしまってから、もう一度openpyxlでファイルをオープンして、
シート内のすべてのセルのプロパティを上記3番目で変更するのが簡単そう。

なお、変更の方法は、
 cell.alignment =  cell.alignment.copy(wrapText=True)
はDepreciatedのwarningが出るので、
 cell.alignment = Alignment(wrap_text=True)
にしてみた。

全体は、
 # "to_Excel"でセル内改行アリが可能か?
 import pandas as pd
 df = pd.DataFrame([['5\n4' ,3], [2,6], [8,5]])   # データ中に\nを入れる
 print(df)
 df.to_excel("mytest2.xlsx")    # とにかくDFのデータからexcelファイルを作ってしまう
 
 import openpyxl
 from openpyxl.styles import Alignment
 wb = openpyxl.load_workbook('mytest2.xlsx')
 ws = wb['Sheet1']
 for row in ws.iter_rows():
     for cell in row:      
         #cell.alignment =  cell.alignment.copy(wrapText=True) # Depreciated警告
         #cell.style.alignment.wrap_text=True    # エラー
         cell.alignment = Alignment(wrap_text=True)  # これなら動いた
 wb.save('mytest2.xlsx')    # ファイルへ書き出し(書き戻し)
これによって実現できる。

**ヒストグラム [#ic4eefe7]

**散布図 [#h1e623b6]

**散布図の各点に値を書く [#b68bb648]
matplotlibのannotateを使う

[[<Python, matplotlib> 散布図の各要素に文字を付ける。 - ねこゆきのメモ:http://nekoyukimmm.hatenablog.com/entry/2015/10/08/224607]]

[[Pandasで散布図を書くとき各要素のラベルを表示 - Qiita:https://qiita.com/kujirahand/items/bdc574102148c7f1f041]]

annotateを使うのにaxが必要なので、たとえば、
 %matplotlib inline
 import pandas as pd
 import matplotlib.pyplot as plt
 df = pd.DataFrame([[1,3,5], [2,4,6]], index=['助教', '教授'], columns=['少ない', 'まあまあ', '多い'])
 dfx = pd.DataFrame(columns=['職階', '評価', '発生数'])
 for ix in df.index:
     for col in df.columns:
         line = [ix, col, df.loc[ix][col]]
         s = pd.Series(line, index=['職階', '評価', '発生数'])
         dfx = dfx.append(s, ignore_index=True)
 print(df)
 print('dfx\n', dfx)
 ax = plt.subplot(1,1,1)  # <-- このようにしてaxを作る
 plt.scatter(dfx['職階'].to_list(), dfx['評価'].to_list(), s=[u*20 for u in 
 dfx['発生数'].to_list()])
 
 for k, v in dfx.iterrows():
     print(v)
     ax.annotate(v[2],xy=(v[0],v[1]),size=14)
 plt.show()


**ヒートマップ [#z0569817]

**階層的クラスタリング [#uec2b39e]
 import numpy as np
 from scipy.cluster.hierarchy import dendrogram, linkage
 from scipy.spatial.distance import pdist
 import matplotlib.pyplot as plt
 X = np.array([[1,2], [2,1], [3,4], [4,3]])
 Z = linkage(X, 'single')  # ward法を使うならば 'single' の代わりに 'ward' を指定する
 dendrogram(
     Z,
     leaf_font_size=8.,  # font size for the x axis labels
 )
 plt.show()

 %matplotlib inline
 import pandas as pd
 import matplotlib.pyplot as plt
 from scipy.cluster.hierarchy import linkage, dendrogram
 df_count_tpm = pd.read_csv("count_tpm.tsv", sep="\t", index_col=0)
 tpm_t = df_count_tpm.T
 print(df_count_tpm.head())
 from scipy.spatial.distance import pdist
 linkage_result = linkage(tpm_t, method='average', metric='correlation')
 plt.figure(num=None, figsize=(16, 9), dpi=200, facecolor='w', edgecolor='k')
 dendrogram(linkage_result, labels=df_count_tpm.columns)
 plt.show()

**k-means法によるクラスタリング [#g269d509]

**mySQLアクセス [#mb48d1b0]
 def read_db(query):
     engine = create_engine('mysql+mysqldb://userid:password@localhost/dbname?charset=utf8',\
                            echo=False)
     dfr = pd.io.sql.read_sql(query, engine)
     return(dfr)
 
 query = 'select * from tablename'
 df = read_db(query)

**ファイルの存在 [#ead665d2]
 import os
 path = "./sample"
 os.path.exists(path)

**pickle [#r9cb401a]
プレーンなPythonの場合

 with open(picklefname, 'rb') as pf:
     df = pickle.load(pf)

 with open(picklefname, 'wb') as pwf:
     pickle.dump(df, pwf)

PandasのDataFrameの場合、(メソッドがある)

 df.to_pickle(picklefname)

 df = pd.read_pickle(picklefname)


** 条件式(3項演算子) [#g859559a]
 x = "OK" if n == 10 else "NG"

**文字列のリストを繋いで1つの文字列にする [#ec82a71e]
 s = ''
 for u in list:
    s += u

'間に挿入する文字列'.join([連結したい文字列のリスト])
 s = ''.join(list)

**文字列の検索 [#i02e3afc]
 >>> "spam".find("pa")
 1
 >>> "spam".find("x")
 -1
indexは見つからないときにエラーを返す

**Seriesに2引数の関数をapplyする場合 [#k62ded28]
 df.x.apply(f1, args=(2,))
 # または、 apply にキーワード引数で与える
 df.x.apply(f1, b=2)

**DF内の検索 [#t51adbc8]
 df[X].isin([list])  listでなければならない。

**pandasで任意の位置の値を取得・変更するat, iat, loc, iloc [#r3974ed5]
 https://note.nkmk.me/python-pandas-at-iat-loc-iloc/

**argv, argc [#v0ea81c0]
 import sys
 argvs = sys.argv;
 argc = len(argvs)
 if (argc != 2):
     print('Usage: python %s filename' % argvs[0])
     quit()

**リストのソート [#k7cb2fe9]
 newls = sorted(list)
メソッドsortはin-placeでソートするので注意。
 list.sort()  # listそのものが置き換わる

**グローバル変数 [#hd2fe0e1]
https://uxmilk.jp/12505
 var = 1
 def add_ten(x):
     global var
     var = 10
     print var + x
  
 add_ten(2)    # 12
 print var     # 10

**リストの差分 [#w1338c7e]
https://python.ms/sub/optimization/if-vs-try/list-deletion/#_6-1-1-%E6%AF%94%E8%BC%83%E5%AF%BE%E8%B1%A1
 def subtract_list(lst1, lst2):
     lst = lst1.copy()
     for e2 in lst2:
         try:
             lst.remove(e2)
         except ValueError:
             continue
     return lst
ifでチェックするより早い

**型のチェック [#yf21f317]
特にNaNがあると、NaNはfloat型だと思い込むので、後の処理でぶつかることがある。

その時に、型チェックで逃げるとすると、(pandas的には個別の型チェックよりはdropnaなどの方がいいと思うが)必要になる。

[[Pythonで型を取得・判定するtype関数, isinstance関数 | note.nkmk.me:https://note.nkmk.me/python-type-isinstance/]]

なのだが、isinstance()の方がよさそうだ。typeで引っかかない場合がある。

**列の型変換 [#la791077]
 df['innings'].astype(np.int64)

**リストの任意の位置への項目挿入 [#aa79d344]
 list.insert(位置, 値)
リストを置き換えるので注意


**絶対値 pythonのabsとmathのfabs、numpyのabs(absolute)、fabs [#z9e9ee09]
pythonのabsは、整数の絶対値は整数、小数の絶対値は小数、複素数の絶対値も可。

mathのfabsは、整数に対しても小数に対しても、絶対値は小数を返す。複素数は不可。

numpyのabs(=absoluteと書いてもいいらしい)は配列ndarrayに対しても適用できる。
もし整数と小数が混ざっていると、小数にする(最大精度)。

numpyのfabsはmathのfabsと同様に、必ず小数を返す。複素数は不可。

**pie chartで生のデータを入れる [#o036590d]
[[python - Pandas pie plot actual values for multiple graphs - Stack Overflow:https://stackoverflow.com/questions/48299254/pandas-pie-plot-actual-values-for-multiple-graphs]]


**ヒストグラム・カウント [#s4f2f043]
 df.hist()
 (df['column']).hist()
 (df['column']).value_counts()
 (df['column']//10*10).value_counts()

カウント結果はSeriesなので、
 s = pd.Series([3, 2, 7, 2, 3, 4])
 u = s.value_counts(sort=False)
 print(u)
 # 2    2
 # 3    2
 # 4    1
 # 7    1
 
 print(type(u))
 <class 'pandas.core.series.Series'>
 
 print(u.index)
 Int64Index([2, 3, 4, 7], dtype='int64')
 
 # カウント結果uをindexでソートすると(黙っていると値の降順でソート)
 print(u.sort_index(ascending=False))
 # 7    1
 # 4    1
 # 3    2
 # 2    2

**matplotlibでsavefigしたときに下が切れる場合 [#b8a7177a]
[[Matplotlib (with seaborn) で出力するPDFの下のほうが切れてしまうときは bbox_inches='tight' - Scala日記:http://ym.hatenadiary.jp/entry/2018/08/16/111900]]

[[bbox_inches = "tight"とかそれ系のやつ - virsalusの日記:http://virsalus.hatenablog.com/entry/2015/01/19/120931]]

 plt.savefig('sample.pdf', bbox_inches='tight')
とするか
 plt.tight_layout()
とするかで対応。

距離行列dmatがあるとき、
 ndmat =squareform(dmat)
 lk = linkage(ndmat,method='average')
 plt.figure(num=None, figsize=(22, 12), dpi=200, facecolor='w', edgecolor='k')
 dendrogram(lk, labels=dmat.index, leaf_rotation=90)
 plt.tight_layout()
 # plt.savefig('corr_coeff_dendrogram.png', bbox_inches="tight")
 plt.savefig('corr_coeff_dendrogram.png')


** XML to Dict [#ica5d9f8]
[[Python: xmltodict を使って XML を辞書へ変換:https://ccieojisan.net/post-1346/]]

** biopython, SNP in feature [#sfc15684]
[[BioPython Tutorial:http://biopython.org/DIST/docs/tutorial/Tutorial.html]]

4.3.2.4  Location testing

You can use the Python keyword in with a SeqFeature or location object to see if the base/residue for a parent coordinate is within the feature/location or not.

For example, suppose you have a SNP of interest and you want to know which features this SNP is within, and lets suppose this SNP is at index 4350 (Python counting!). Here is a simple brute force solution where we just check all the features one by one in a loop:

 >>> from Bio import SeqIO
 >>> my_snp = 4350
 >>> record = SeqIO.read("NC_005816.gb", "genbank")
 >>> for feature in record.features:
 ...     if my_snp in feature:
 ...         print("%s %s" % (feature.type, feature.qualifiers.get("db_xref")))
 ...
 source ['taxon:229193']
 gene ['GeneID:2767712']
 CDS ['GI:45478716', 'GeneID:2767712']

Note that gene and CDS features from GenBank or EMBL files defined with joins are the union of the exons &#8211; they do not cover any introns.


**Matplotlibで、複数のfigureを1つのPDFファイルに保存する方法 [#lda0034f]
[[matplotlibで複数のfigureを一つのpdfに保存する - Qiita:https://qiita.com/ceptree/items/c7b18fdf938ec1b5021e]]

 import matplotlib.pyplot as plt
 from matplotlib.backends.backend_pdf import PdfPages  # <-- 追加
 
 pdf = PdfPages('ファイル名.pdf')   # <-- 追加 (pdfをオープン)
 
 for ... :   # 複数枚作る
     plt.scatter(....)    # plotして図を作る
     pdf.savefig()   #  <-- savefigの行先はpdfになる
     plt.show()    # <-- 画面表示

 pdf.close()   # <-- 最後に忘れないように 


**Seaborn heatmapで上下単が切れる問題 [#j4fcdba6]
[[seabornのheatmapでy軸が足りなくて、annotが活用できない - Qiita:https://qiita.com/yoshi65/items/90532732bf9d3875bec7]]

バージョンアップで解決。古いバージョンの時は逃げる方法がある。
ax.set_ylim(len(flights), 0)

**Seaborn heatmapまわり [#x9109b9e]
***とりあえずマニュアル [#v4bf727c]
[[seaborn.heatmap &#8212; seaborn 0.9.0 documentation:https://seaborn.pydata.org/generated/seaborn.heatmap.html]]

*** annotation [#s2ce3c29]
fmtの指定: fmt='.2f'とかfmt='d'とか

***カラーパレット [#u346c5db]
[[Seabornのカラーパレットの選び方 - Qiita:https://qiita.com/SaitoTsutomu/items/c79c9973a92e1e2c77a7]]

[[Seabornで相関をヒートマップにする(行・列を並び替えながら) / Heatmap using Seaborn (order rows and columns as you like) - Qiita:https://qiita.com/Ken-Kuroki/items/81a09c956118e04cd00f]]

[[seabornの細かい見た目調整をあきらめない - Qiita:https://qiita.com/skotaro/items/7fee4dd35c6d42e0ebae]]

annot_kws={'fontsize': 9, 'color': 'green'} とかできる。

**連関係数の計算に使えるCrosstab [#d394122a]
[[crosstab() &#8212; researchpy 0.1.1 documentation:https://researchpy.readthedocs.io/en/latest/crosstab_documentation.html]]


〜〜〜〜〜〜〜〜〜〜〜〜

**おまけ bashのループ [#m8969d16]
 #!/usr/bin/bash
 samples=("Anc" "1_2-1" "2_2-1" "2_5-1" "2_5-1-7A" "1_2-2" "2_2-2" "2_6-2" "2_6-2-10E")
 for f in "${samples[@]}"
 do
   #nohup python ProcessGD.py $f > $f.out &
   echo $f
 done

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS