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

*pandasティップス [#gfafdcc8]
**行選択と列選択 [#s06c1b34]
***行位置選択 [#ocd73bc9]

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

**セル選択 [#l2d0b6fa]

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

**行間での足し算 [#p4eda8c1]
 import pandas as pd
 df = pd.DataFrame([['A', 1, 3], ['B', 2, 4], ['C', 3, 5], ['D', 4, 6]], \
                   columns=['a', 'b', 'c'])
 print(df)
 #   a  b  c
 #0  A  1  3
 #1  B  2  4
 #2  C  3  5
 #3  D  4  6
 
 print(df[df.index.isin([2, 3])].sum())  # リストにある行を足す
 #a    CD
 #b     7
 #c    11
 #dtype: object
 
 print(df.loc[0:1].sum())  # 連続した行を足す
 #a    AB
 #b     3
 #c     7
 #dtype: object
 
 print(df.loc[[0,2]].sum()) # (リストにある)とびとびの行でもOK
 #a    AC
 #b     4
 #c     8
 #dtype: object

おまけ、平均
 print(df[df.index.isin([2, 3])].mean())
 #b    3.5
 #c    5.5
 #dtype: float64
 
 print(df.loc[0:1].mean())
 #b    1.5
 #c    3.5
 #dtype: float64

**pandas DataFrameで数値の桁数を丸めるには [#o7af6fd8]
-表示だけ丸める~
[[pandasの表示設定変更(小数点以下桁数、有効数字、最大行数・列数など) | note.nkmk.me
https://note.nkmk.me/python-pandas-option-display/]]
 pd.options.display.precision = 2  # すべての表示を小数点以下2桁に丸める

-数値そのものを丸める(描画で字を書くとか)
 df.round(2)  # すべてを小数点以下2桁に丸める

**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)

正規表現を使って置き換えを指定することができる。
 print(df.replace('(.*)li(.*)', r'\1LI\2', regex=True))
のように、regex=Trueで指定する。(デフォルトはFalse)~
正規表現の指定の仕方は、たとえば[[Pythonの正規表現モジュールreの使い方(match、search、subなど) | note.nkmk.me:https://note.nkmk.me/python-re-match-search-findall-etc/]]を参照。

**内包の2重ループ [#n4389b35]
[[Python のネストした内包表記 - Qiita:https://qiita.com/propella/items/fa64b40b6f45d4f32cbc]]

 [(x, y) for x in [1, 2] for y in ['a', 'b', 'c']]

yが内側ループ、xが外側ループになることに注意。

**もう1つの(条件付きの)要素データの置き換え where [#l3d18696]
条件付きの要素書換えは、whereで書くことができる。

[[pandasで条件に応じて値を代入(where, mask) | note.nkmk.me:https://note.nkmk.me/python-pandas-where-mask/]]

whereを使って、第3引数に新しい値を指定することによって、書き換えることができる。

1列'A'を書き換える例
 df['D'] = df['A'].where(df['C'] == 'a', 100)     # 定数を書込む
 df['D'] = df['A'].where(df['C'] == 'a', df['B']) # df['B']から値を持ってくる
但し、「書換え」操作として見ると条件指定は逆(Trueだと書き換えない)になっているので注意。その理由は、whereが(第3引数を指定しないと)条件がTrueの要素だけを元の値を抜き出し、Falseの要素はNaNを返すような元々の機能だから。つまりTrueはそのままで、Falseだと何かするが、その「何か」が第3引数があればその値、第3引数が指定されていなければNaNとなる。

データフレーム全体で書き換える例
 df2 = df.where(df < 0, 100)
 df2 = df.where(df < 0, df * 2)


**列名の付け替え 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

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

**MultiIndexまわり [#u34e5dee]
MultiIndexのDF/Seriesから要素を指定するには ⇒ xs()メソッドが見やすい

[[pandasのMultiIndexから任意の行・列を選択、抽出 | note.nkmk.me:https://note.nkmk.me/python-pandas-multiindex-indexing/]]


 print(df.xs(インデックス名, level='レベル名))
たとえば
                          val_1  val_2
 level_1 level_2 level_3              
 A0      B0      C0          98     90
                 C1          44      9
         B1      C2          39     17
                 C3          75     71
 A1      B2      C0           1     89
                 C1          54     60
         B3      C2          47      6
                 C3          16      5
 A2      B0      C0          75     22
                 C1          19      4
         B1      C2          25     52
                 C3          57     40
に対して、
 print(df.xs('B1', level='level_2'))  # level_2が'B1'である行を選択
とすると
 #                  val_1  val_2
 # level_1 level_3              
 # A0      C2          39     17
 #         C3          75     71
 # A2      C2          25     52
 #         C3          57     40

[[pandasのMultiIndexから任意の行・列を選択、抽出 | note.nkmk.me:https://note.nkmk.me/python-pandas-multiindex-indexing/]]

 #multindex
 import pandas as pd
 
 # Create DF
 columns = ['level_1','level_2','level_3','val_1','val_2']
 l = \
 [['A0',      'B0',      'C0',     98,     90],
  ['A0',      'B0',      'C1',     44,      9],
  ['A0',      'B1',      'C2',     39,     17],
  ['A0',      'B1',      'C3',     75,     71],
  ['A1',      'B2',      'C0',      1,     89],
  ['A1',      'B2',      'C1',     54,     60],
  ['A1',      'B3',      'C2',     47,      6],
  ['A1',      'B3',      'C3',     16,      5],
  ['A2',      'B0',      'C0',     75,     22],
  ['A2',      'B0',      'C1',     19,      4],
  ['A2',      'B1',      'C2',     25,     52],
  ['A2',      'B1',      'C3',     57,     40],
  ['A3',      'B2',      'C0',     64,     54],
  ['A3',      'B2',      'C1',     27,     96],
  ['A3',      'B3',      'C2',    100,     77],
  ['A3',      'B3',      'C3',     22,     50]]
 df = pd.DataFrame(l, columns=columns)
 print(df)
 df_m = df.set_index(['level_1', 'level_2', 'level_3'])  # muyltiIndex化
 print()
 print(df_m)
 print()
 print(df_m.xs('B1', level='level_2'))  # xsによるアクセス
 print()
 
 df_T = df_m.T    # 転置でmultiColumn化
 print(df_T)
 print()
 print(df_T.xs('B1', level='level_2', axis=1))  # xsはaxis=1でmultiColumnに対応

結果は
    level_1 level_2 level_3  val_1  val_2
 0       A0      B0      C0     98     90
 1       A0      B0      C1     44      9
 2       A0      B1      C2     39     17
 3       A0      B1      C3     75     71
 4       A1      B2      C0      1     89
 5       A1      B2      C1     54     60
 6       A1      B3      C2     47      6
 7       A1      B3      C3     16      5
 8       A2      B0      C0     75     22
 9       A2      B0      C1     19      4
 10      A2      B1      C2     25     52
 11      A2      B1      C3     57     40
 12      A3      B2      C0     64     54
 13      A3      B2      C1     27     96
 14      A3      B3      C2    100     77
 15      A3      B3      C3     22     50
 
                          val_1  val_2
 level_1 level_2 level_3              
 A0      B0      C0          98     90
                 C1          44      9
         B1      C2          39     17
                 C3          75     71
 A1      B2      C0           1     89
                 C1          54     60
         B3      C2          47      6
                 C3          16      5
 A2      B0      C0          75     22
                 C1          19      4
         B1      C2          25     52
                 C3          57     40
 A3      B2      C0          64     54
                 C1          27     96
         B3      C2         100     77
                 C3          22     50
 
 
                   val_1  val_2
 level_1 level_3              
 A0      C2          39     17
         C3          75     71
 A2      C2          25     52
         C3          57     40
 
 level_1  A0              A1              A2              A3             
 level_2  B0      B1      B2      B3      B0      B1      B2       B3    
 level_3  C0  C1  C2  C3  C0  C1  C2  C3  C0  C1  C2  C3  C0  C1   C2  C3
 val_1    98  44  39  75   1  54  47  16  75  19  25  57  64  27  100  22
 val_2    90   9  17  71  89  60   6   5  22   4  52  40  54  96   77  50
 
 level_1  A0      A2    
 level_3  C2  C3  C2  C3
 val_1    39  75  25  57
 val_2    17  71  52  40





**SeriesからDataFrameへ変換 [#i5b94365]
 s = pd.Series(['A','B','C'])
 df = pd.DataFrame([s])
 print(df)

 #    0  1  2
 # 0  A  B  C

そこで転置すると
 df = pd.DataFrame([s]).T
 print(df)

 #    0
 # 0  A
 # 1  B
 # 2  C

もう少し例を:
 #multindex
 import pandas as pd
 # Create DF
 columns  = ['level_1','level_2','level_3','val_1','val_2', 'val_3']
 
 l = \
 [[ 'X0',      'Y0',      'Z0',      'U',      'U',    'V'],
  [ 'X1',      'Y1',      'Z1',      'P',      'Q',    'P'],
  [ 'A0',      'B0',      'C0',     98,     90,    5],
  [ 'A0',      'B0',      'C1',     44,      9,    4],
  [ 'A0',      'B1',      'C2',     39,     17,    3],
  [ 'A0',      'B1',      'C3',     75,     71,    2],
  [ 'A1',      'B2',      'C0',      1,     89,    1],
  [ 'A1',      'B2',      'C1',     54,     60,    9],
  [ 'A1',      'B3',      'C2',     47,      6,    8],
  [ 'A1',      'B3',      'C3',     16,      5,    7],
  [ 'A2',      'B0',      'C0',     75,     22,    6],
  [ 'A2',      'B0',      'C1',     19,      4,    51],
  [ 'A2',      'B1',      'C2',     25,     52,    52],
  [ 'A2',      'B1',      'C3',     57,     40,    53],
  [ 'A3',      'B2',      'C0',     64,     54,    54],
  [ 'A3',      'B2',      'C1',     27,     96,    55],
  [ 'A3',      'B3',      'C2',    100,     77,    56],
  [ 'A3',      'B3',      'C3',     22,     50,    57]]
 df = pd.DataFrame(l, columns=columns)
 print(df)
 df_m = df.set_index(['level_1', 'level_2', 'level_3'])  # multiIndex化
 print()
 print(df_m)
 print()
 print(df_m.xs('B1', level='level_2'))  # xsによるアクセス
 print()
 df_T = df_m.T    # 転置でmultiColumn化
 print('df_T\n', df_T)
 print()
 #print(df_T.xs('B1', level='level_2', axis=1))  # xsはaxis=1でmultiColumnに対応
 
 df_X = df_T.set_index([('X0', 'Y0', 'Z0'), ('X1', 'Y1', 'Z1')])
 print(df_X.index)
 index = pd.MultiIndex.from_tuples(df_X.index, names=['First', 'Second'])
 df_X.index = index
 print('df_X\n', df_X)
 print()
 df_Y = df_X.xs('B1', level='level_2', axis=1)  # xsによるアクセス
 print('df_Y\n', df_Y)
 print()
 print(df_Y.index)
 df_R = df_Y.reset_index(level=('X0', 'Y0', 'Z0'))
 print('df_R\n', df_R)

この辺がよさそうだ。pd.MultiIndex.from_tuple()を使う
-[[pandas.DataFrame.set_index &#8212; pandas 0.23.4 documentation:https://pandas.pydata.org/pandas-docs/version/0.23.4/generated/pandas.DataFrame.set_index.html]]
-[[pandas.DataFrame.reset_index &#8212; pandas 0.23.4 documentation:https://pandas.pydata.org/pandas-docs/version/0.23.4/generated/pandas.DataFrame.reset_index.html]]

 import pandas as pd
 index = pd.MultiIndex.from_tuples([('bird', 'falcon'),
                                    ('bird', 'parrot'),
                                    ('mammal', 'lion'),
                                    ('mammal', 'monkey')],
                                    names=['class', 'name'])
 columns = pd.MultiIndex.from_tuples([('speed', 'max'),
                                      ('species', 'type')])
 df = pd.DataFrame([(389.0, 'fly'),
                    ( 24.0, 'fly'),
                    ( 80.5, 'run'),
                    (np.nan, 'jump')],
                   index=index,
                   columns=columns)
 print(df)
 
 #print(df.reset_index())
 #print(df.reset_index(level='class'))
 
 # column名変更?
 columns = pd.MultiIndex.from_tuples([('P', 'Q'),
                                      ('R', 'S')])
 df_R = df.copy()
 df_R.columns = columns
 print('df_R\n', df_R)
 df_RR = df.copy()
 df_RR[('P', 'Q')] = df[('speed', 'max')]
 df_RR = df_RR.drop(('speed', 'max'), axis=1)
 print('df_RR\n', df_RR)
 
 print()
 print('reset\n', df_RR.reset_index(level='name'))

**辞書の反転 [#j3823388]
[[Pythonで辞書のキーと値を入れ替える | note.nkmk.me:https://note.nkmk.me/python-dict-swap-key-value/]]
 d_swap = {v: k for k, v in d.items()}

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

DataFrameの2つの列の間の関係を辞書にするためには、
-キー側の列の値をindexとし、
-値を(列値として)並べたSeriesを作る ~
DataFrameからSeriesを作るには、Ser = DF['カラム名']とする。(四角括弧が一重)
-そのSeriesを、ser.to_dict() で辞書型に変換する

 pair = df[['キー側', 'バリュー側']]
 ser = pair['バリュー側']
 ser.index = pair['キー側']
 dic = 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の列が残る。

単に個数をカウントしたい場合、関数count()を使ってよい。~
単に個数をカウントしたい場合、下記のsize()でもよいし、関数count()を使ってよい。~
[[Pandasでデータの個数を数え上げるcount関数の使い方 - DeepAge:https://deepage.net/features/pandas-count.html#groupby%E3%81%A8count%E3%81%AE%E4%BD%B5%E7%94%A8]]

 dfcount = df.groupby('city').count()
 print(dfcount)
 #       food  price  quantity
 #city                        
 #osaka     4      4         4
 #tokyo     3      3         3
 
 dfcount = df.groupby('city')[['food']].count().rename(columns={'food': 'count'})
 print(dfcount)
 #       count
 #city        
 #osaka      4
 #tokyo      3


**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.DataFrame([[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 )

あとから列を足すのは、縦のデータの長さが同じなら簡単で、上記の場合縦が4なので
 df['NEW'] = [3, 4, 5, 6]

長さが異なる場合、上記の方法はエラーになる。Seriesを作って同じように書きこめばOK.

 ## Test 〜 convert list (with different length) to DF column
 import pandas as pd
 import numpy as np
 
 list1 = [1, 2, 3]
 list2 = [4, 5, 6, 7, 8]
 list3 = [10, 11]
 
 # リストの長さがすべて同じならば、単純にdf['新列名']=listでOK
 # 長さが異なるとエラー
 df = pd.DataFrame(index=[0, 1, 2, 3, 4], columns=[])
 #df['A'] = list1  <-- 長さが違うのでエラー
 
 s = pd.Series(list1, index=[0,1,2])
 df['A'] = s
 print(df)  # これだと、不足した要素部分はNaN
 #     A
 #0  1.0
 #1  2.0
 #2  3.0
 #3  NaN
 #4  NaN
 
 df.to_excel('mytest.xlsx')  # NaNの場所はExcel上では空欄になる
 
 df = df.replace(np.nan, '')  # nanを空文字列に置換え
 print(df)
 #   A
 #0  1
 #1  2
 #2  3
 #3   
 #4   
 
 df.to_excel('mytest2.xlsx')  # 空文字列の場所はExcel上では空欄になる


**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', ...)


**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')

または、withを使わない方法として
 writer = pd.ExcelWriter('output.xlsx')
 ...
 df1.to_excel(writer, sheet_name='Sheet_name_1')
 df2.to_excel(writer, sheet_name='Sheet_name_2')
 ...
 writer.save()  # <-- これが必要
 writer.close() # <-- これが必要


**read_excelでパスワード付きのExcelファイルを読む場合 [#i67f69bd]
-[[Pythonでパスワード付Excelファイルを読む - Qiita:https://qiita.com/kira4845/items/b8182414370dffccc217]]
-[[パスワード付きExcelをPythonで読み込む方法(Linux対応) - Qiita:https://qiita.com/suk1yak1/items/526388f47a781ef10eb4]]

パスワード機能を直接pandas(やopenxylx, xlrd)に取り込む話は難しいようだ。
 pip install msoffcrypto-tool

 import tempfile
 import msoffcrypto
 import pandas as pd
 from pathlib import WindowsPath
 file_dir = WindowsPath(r"アンケートが入ったディレクトリのパス")
 # 回答ファイルを順次確認
 for file in file_dir.glob("*.xlsm"):
     # パスワード解除したテンポラリファイル作成
     with file.open("rb") as f, tempfile.TemporaryFile() as tf:
         office_file = msoffcrypto.OfficeFile(f)
         office_file.load_key(password="パスワード")
         office_file.decrypt(tf)
         # テンポラリファイルから回答をロード
         df = pd.read_excel(tf, header=None)


**read_excelで階層カラムを読む場合 [#y5d834d4]
[[pandasで複数行ヘッダーを持つExcelファイルを読込みカラム(columns)を整形する - Qiita:https://qiita.com/noca/items/966f4c5ae5eee8195fe0]]

&ref(./階層カラムの例.png,400x300);

 df = pd.read_excel(filename, sheet_name='xxx', skiprows=y, header=[u, v, w])
これで、まず先頭y行分をスキップした後、headerで列名部分を読むが、(スキップした後の)u行目、v行目、w行目をそれぞれ第1階層・第2階層・第3階層の列名とする。

**階層カラムをフラット化する [#d671a93d]
[[python - pandas DataFrameで階層列インデックスをフラット化するにはどうすればよいですか? - ITツールウェブ:https://ja.coder.work/so/python/940043]]
    A     B   
    a  b  a  b
 0  0  1  2  3
 1  4  5  6  7
を
    Aa  Ab  Ba  Bb
 0   0   1   2   3
 1   4   5   6   7
のようにしたい、と言う場合。

列名を書き直すとすれば、
 df.columns = df.columns.map(''.join)

万が一列名が文字列でない場合は、文字列に変換
 df.columns = df.columns.map(lambda x: ''.join([*map(str, x)]))
をしてからjoinする必要がある。

**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')    # ファイルへ書き出し(書き戻し)
これによって実現できる。


**matplotlib描画出力(figデータ)をイメージデータとして扱う方法 [#w38377db]
matplotlibで描いた図をイメージデータに作ることができる。あまり美しくはないが。

[[PythonのMatplotlibのグラフをNumPy行列に変換してOpenCVやPillowで使う &#8212; 某エンジニアのお仕事以外のメモ(分冊):https://water2litter.net/rum/post/python_matplotlib_convert2array/]]

 from matplotlib import pyplot as plt
 import numpy as np
 from PIL import Image
 
 x = np.linspace(0, 2*np.pi, 21)
 y1 = np.sin(x)
 y2 = np.cos(x)
 y3 = y1-y2
 fig, ax = plt.subplots()
 ax.plot(x, y1, 'b.-')
 ax.plot(x, y2, 'g,-.')
 ax.plot(x, y3, 'r,-.')
 
 fig.canvas.draw()
 #im = np.array(fig.canvas.renderer.buffer_rgba())
 im = np.array(fig.canvas.renderer._renderer) # matplotlibが3.1より前の場合
 
 img = Image.fromarray(im)
 img.show() # これはjupyter notebook上で動いた PILのim.show()の出力はXwinへ行く


もう1つの例は(rendererの出力を文字にする)
[[How to convert a matplotlib figure to a numpy array or a PIL image | ICARE Data and Services Center:http://www.icare.univ-lille1.fr/tutorials/convert_a_matplotlib_figure]]

 import matplotlib.pyplot as plt
 import numpy as np
 from PIL import Image
 
 # make an agg figure
 fig, ax = plt.subplots()
 ax.plot([1, 2, 3])
 ax.set_title('a simple figure')
 
 fig.canvas.draw()
 
 # grab the pixel buffer and dump it into a numpy array
 #X = np.array(fig.canvas.renderer.buffer_rgba()) # これはダメだった
 w,h = fig.canvas.get_width_height()
 buf = np.frombuffer( fig.canvas.tostring_argb(), dtype=np.uint8 )
 buf.shape = ( w, h,4 )
 # canvas.tostring_argb give pixmap in ARGB mode. Roll the ALPHA channel to have 
 it in RGBA mode
 buf = np.roll ( buf, 3, axis = 2 )
 
 w, h, d = buf.shape
 im = Image.frombytes( "RGBA", ( w ,h ), buf.tostring( ) )
 im.show()
 
 # これはjupyter notebook上で動いた PILのim.show()の出力はXwinへ行く


**複数の図(subplot)を1枚の図にする時 [#p29f33cc]
subplotsを使って指定できる。
 fig, ax = plt.subplots( ncols=len(xdata), nrows=len(ydata), figsize=(6*len(xdata), 6*len(ydata))
 ...
 for i, x in xdata:
   for j, y in ydata:
     sns.kdeplot(data[i], data[j], ax=ax[j,i], shade=True)
 plt.show()

***subplotで図の間隔が狭いときは [#n5386312]
subplots_adjustを使う
 plt.subplots_adjust(wspace=0.4, hspace=0.6)
デフォルトは0.2, 0.2らしい。大きくすると広がる。枚数による。

**ヒストグラム [#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()

[[Pandasで散布図を書くとき各要素のラベルを表示 - Qiita:https://qiita.com/kujirahand/items/bdc574102148c7f1f041]]ではaxを作る代りに、
 import pandas as pd
 
 # DataFrameにデータをセット
 dd = pd.DataFrame([
         [10,50,'hoge'],
         [50,30,'fpp'],
         [20,30,'baa']
     ], columns=['ax','ay','label'])
 
 # 散布図を描画
 a = dd.plot.scatter(x='ax',y='ay')
 # 各要素にラベルを表示
 for k, v in dd.iterrows():
     a.annotate(v[2], xy=(v[0],v[1]), size=15)
のように、a = df.plot.scatter() としておいて、このaに対して a.annotate()。


**pandasのplotでx軸ラベルの文字の向きを回転させる [#b6ffac5c]
裸のmatplotlibでは
 plt.xticks(rotation=90)
などとする。90は右90度回転(縦書き、これがデフォルト)。横書きにするにはrotation=0。

pandasのplotの場合は、上記のxticksを加えてもよいが、plotの引数に指定することもできる。たとえば
 df.plot(kind='bar', rot=0)
 df.plot.bar(rot=0)
いずれも、角度の指定はxticksと同様で、0が横書きになるが、デフォルトは90の縦書き。


**matplotlibで凡例legendの位置を調整する [#o35e6d61]
 plt.legend(bbox_to_anchor=(0.005, 0.995), loc='upper left', borderaxespad=0)
や
 plt.legend(bbox_to_anchor=(1.005, 0.995), loc='upper left', borderaxespad=0)


**凡例のテキストを変更する [#z7a8b48e]
[[python - Modify the legend of pandas bar plot - Stack Overflow:https://stackoverflow.com/questions/33149428/modify-the-legend-of-pandas-bar-plot]]

1本ごとにpltを呼んでいるとき(pandasではなくて生のmatplotlibの時)
 plt.plot.bar(... label='自分のテキスト', ...)
で指定できる。

pandasでDataFrameを一気に描いてしまう(列ごとに描画など)ときは、1つ目は
plt.legend()で、リストを指定できる。
 df = pd.DataFrame({'A':26, 'B':20}, index=['N'])
 ax = df.plot(kind='bar')
 ax.legend(["AAA", "BBB"]);

1つのfigure内に複数のaxが存在してもいい。
 fig, ax = plt.subplots(nrows=1, ncols=len(years), figsize=(8*len(years), 6))
 for i, year in enumerate(years):
    dfhx.plot.line(ax=ax[i])
    ax[i].legend([図i用の、線の数に対応したリスト])

** 凡例の表示順序を反転する [#ef9d3b9f]
[[Legend guide &#8212; Matplotlib 1.3.1 documentation:https://matplotlib.org/1.3.1/users/legend_guide.html]]
 ax = subplot(1,1,1)
 p1, = ax.plot([1,2,3], label="line 1")
 p2, = ax.plot([3,2,1], label="line 2")
 p3, = ax.plot([2,3,1], label="line 3")
 
 handles, labels = ax.get_legend_handles_labels()
 
 # reverse the order
 ax.legend(handles[::-1], labels[::-1])
自分のプログラムでは、
 # df2を準備しておく
 a = df2.plot.bar(stacked=True)
 plt.title(lvl1[0]+'/'+lvl2)
 handles, labels = a.get_legend_handles_labels()
 plt.legend(handles[::-1], labels[::-1], bbox_to_anchor=(1.005, 0.995), loc='upper left', borderaxespad=0)
 pdf.savefig(bbox_inches='tight')
 plt.show()


** 散布図で上記annotationを加えたときに文字が重なるのを防ぐ [#n4c36725]
[[いるかのボックス: Matplotlibでテキストラベルを重ならないように表示する:https://irukanobox.blogspot.com/2019/12/matplotlib.html]]

散布図で点のラベルを入れたときに、数が多いと、重なり合って読めなくなることがある。それを避けるには、adjust_textライブラリが使える。(adjustとtextの間に下線があったりなかったりなので要注意)

 pip install adjusttext
でインストールした後、
 from adjustText import adjust_text
 ...
 texts = []
 a = dfout.plot.scatter(x='重要度', y='満足度')
 for k, v in dfout.iterrows():
     u = a.annotate(v[2], xy=(v[0],v[1]), size=10)
     texts.append(u)
 plt.title('...')
 adjust_text(texts)
 plt.savefig(...)
 plt.show()
これで、かなりの場合自動的に位置を決めてくれる。(但し遅くなるらしい)

複数のプロットがある場合、axを指定してadjust_textをする必要がある。指定しないと位置もずれる。

[[With multiple subplots, run adjust_text for one subplot at a time:https://adjusttext.readthedocs.io/en/latest/Examples-for-multiple-subplots.html#With-multiple-subplots,-run-adjust_text-for-one-subplot-at-a-time]]

 fig, axes = plt.subplots(1, 2, figsize=(8, 3))
 for k, ax in enumerate(axes):
    ...
    ax.plot(x, y, 'bo')
    ...
    texts = []
    for i in range(len(x)):
        t = ax.text(x[i], y[i], 'Text%s' %i, ha='center', va='center')
        texts.append(t)
    adjust_text(texts, ax=ax)


**matplotlibで軸のメモリの文字を変更するには [#ib5188b5]
[[matplotlib - 目盛、目盛のラベル、グリッドの設定方法 - Pynote:https://www.pynote.info/entry/matplotlib-xticks-yticks-grid#%E7%9B%AE%E7%9B%9B%E3%82%8A%E3%81%AB%E5%AF%BE%E5%BF%9C%E3%81%99%E3%82%8B%E3%83%A9%E3%83%99%E3%83%AB%E3%82%92%E8%A8%AD%E5%AE%9A%E3%81%99%E3%82%8B]]

ax.set_xticklabels(リスト)、ax.set_yticklabels(リスト)で設定すればよいらしい。
但しリストの個数は元の個数(つまりxticksでの個数)に合わせる必要がありそう。
例題では、
 # x 軸 (major) の目盛りを設定する。
 ax.set_xticks(np.linspace(0, np.pi * 4, 5))
 # x 軸 (major) の目盛りのラベルを設定する。
 ax.set_xticklabels(["0", "$1\pi$", "$2\pi$", "$3\pi$", "$4\pi$"])
 
 # y 軸 (major) の目盛りを設定する。
 ax.set_yticks(np.linspace(-1, 1, 3))
 # y 軸 (major) の目盛りのラベルを設定する。
 ax.set_yticklabels(["A", "B", "C"])
のようにしている。自分の例では、
 a = dfhxzout.plot.line(ax=ax[i], marker='x', xticks=range(len(DHankelist[col])), \
       title=year+'年入学 入学時 '+col, rot=90)
 a.set_xticklabels([u[3:8] for u in DHankelist[col]])


**ヒートマップ [#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()

クラスター自体を取出したい時は fcluster が使える。
 import numpy as np
 from scipy.cluster.hierarchy import dendrogram, linkage, fcluster
 from scipy.spatial.distance import pdist
 import matplotlib.pyplot as plt
 X = np.array([[1,2], [2,1], [3,4], [4,3], [1,3], [3,1]])
 Z = linkage(X, 'single')  # ward法を使うならば 'single' の代わりに 'ward' を指定する
 plt.figure(figsize=(20,20), dpi=200, facecolor='w', edgecolor='k')
 dendrogram(
     Z,
     leaf_font_size=8.,  # font size for the x axis labels
     labels = ['A', 'B', 'C', 'D', 'E', 'F']
 )
 plt.savefig('dendrogram.pdf')
 plt.show()
 
 NUM_CLUSTERS = 5
 nodelabels = ['A', 'B', 'C', 'D', 'E', 'F']
 for num in range(5, NUM_CLUSTERS+1):
     labels = fcluster(Z, t=num, criterion='maxclust')
     #fclusterは、入力がどのクラスタに属するか(クラスタ番号 labels)を返す
     print(num, labels)
     # クラスタごとに、それに属する入力をリストとして表示
     for cl_id in range(1, num+1):
         l = [nodelabels[n] for n in range(0,len(labels)) if labels[n]==cl_id]
         print(' ', cl_id, l)
出力は&ref(./test_dendrogram.png,200x200);

fclusterの出力:
 5 [1 2 3 4 1 2]  # リストに各要素のクラスタid(1〜4)。第1要素と第5要素はクラスタ1に、第2と第6はクラスタ2に属する
それを書き直した結果:
   1 ['A', 'E']   # 上記を、クラスタ1には要素1と5が属すると変形し、更に要素id(1,5)をラベル(A,E)に置換えた
   2 ['B', 'F']
   3 ['C']
   4 ['D']
   5 []

**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そのものが置き換わる

**リストのflatten [#bdcafeb5]
#   Python 3 で flatten する方法いろいろ
#   https://qiita.com/hoto17296/items/e1f80fef8536a0e5e7db

 sum([[1,2,3],[4,5,6],[7,8,9]], [])  #=> [1, 2, 3, 4, 5, 6, 7, 8, 9]

第2引数の[]が必要。これは、第2引数のデフォルト値が0なので数値の+だと思い込むから。

 l = [['A', 'B', 'C'], ['D', 'E'], ['F']]
 print(sum(l, []))


**グローバル変数 [#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()

[[Pandasでデータの値の頻度を計算するvalue_counts関数の使い方 - DeepAge:https://deepage.net/features/pandas-value-counts.html]]

カウント結果は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


科目別の成績データをGroupByで集計整理し、点数ヒストグラムを描く例
 # df が入力の科目別成績データ 
 df = df[['学籍番号', '学科', '入学年度', '取得素点']]
 dfmean = df.groupby('学籍番号').mean()  # 1人1人の在学中の評点平均
 dfgakka = dfmean.groupby(['学科', '入学年度'])['取得素点'].apply(lambda d: (d//5*5).value_counts(bins=list(range(0,101,5))).sort_index()) 
 # dfgakkaは、Seriesで、indexが ('学科', '入学年度', '評点の5点刻みのクラス')の3レベル
    
 for year in [2010, 2011, 2012, 2013, 2014, 2015]:
     # DataFrameに直す
     for gakka in [51, 52, 53, 54, 55, 56]:    # 学科ごとに列にする
         ser = dfgakka.xs(year, level='入学年度').xs(gakka, level='学科')
         if gakka==51:
             dfout = pd.DataFrame(ser)
             dfout.columns = [gakka]
         else:
             dfout[gakka] = ser
     dfout = dfout.rename(columns=gakkaname)
     dfout.index = [u.left for u in dfout.index.to_list()]
     #dfoutx.plot.bar(figsize=(8,6), rot=0)
     dfout.plot.line(figsize=(8,6), marker='x', rot=0, xticks=[u for u in dfout.index.to_list()])
     plt.title('通算評点頻度分布 '+str(year)+' 年入学')
     plt.xlabel('平均通算評点')
     plt.ylabel('人数')
     plt.legend(bbox_to_anchor=(1.01, 0.995), loc='upper left', borderaxespad=0)
     pdf.savefig(bbox_inches='tight')
     plt.show()
またヒストグラムが人数の代わりに%にするには
     dfm = dfout.sum()
     dfm = dfout/dfm*100
     dfm = dfm.rename(columns=gakkaname)
     #dfm.plot.bar(figsize=(8,6), rot=0)
     dfm.plot.line(figsize=(8,6), marker='x', rot=0, xticks=[u for u in dfm.index.to_list()])


**特定条件を満たす要素数をカウント [#sd6c945e]
[[pandasで特定の条件を満たす要素数をカウント(全体、行・列ごと) | note.nkmk.me:https://note.nkmk.me/python-pandas-count-condition/]]

たとえば
 df['age']<25
はdf中の25未満のデータに対してTrueを入れたSeriesを返すから
 (df['age']<25).sum()
によって個数を数えることができる。(Trueは1、Falseは0)

単にデータの個数(NaNでないデータの個数)を数えるだけなら、
 df.count()   # 列ごと(縦)にカウント
 df.counts(axis=1)   # 行ごと(横)にカウント
が使える。

**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()   # <-- 最後に忘れないように 


** pandas plot.barでX軸目盛の文字が縦を向かない件 [#l3ea0ec0]

DataFrame df を df.plot.bar() でグラフ表示するとき、X軸目盛の文字が
横向きになってしまう。

いろいろやってわかったのは、
 df.plot.bar(y='カラム名')
とすると正しく表示されるが、
 df.plot.bar()
だとダメ。y=を書かないスタイルは、すべてのカラムが表示されるので具合がいい。
dfに1つしかカラムがなければそれで済むし、複数あればそれらがみな表示される。
ラベルのことさえ気にしなければこれでも十分だろう)

また、xticksを使って回転させるワザは働かなかった。たとえば
 plt.xticks(rotation=90)
とかは効かなかった。


**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]]


*PythonからPDFが書き出せるreportlab [#x2283b9c]
[[ReportLab - Content to PDF Solutions:https://www.reportlab.com/]]

-[[PythonのPDFライブラリ「ReportLab」の使い方(用紙サイズ、向き、文字出力、改ページ) - Symfoware:https://symfoware.blog.fc2.com/blog-entry-769.html]]
-[[PythonのReportLabで、表(TableやTableStyle)について調べてみた - メモ的な思考的な:https://thinkami.hatenablog.com/entry/2017/01/19/062615]]
-[[reportlab の Table で日本語を使う - Qiita:https://qiita.com/ekzemplaro/items/a3e3d4419a560f3185e3]]
-[[reportlab の Table の表示位置をコントロールする - Qiita:https://qiita.com/ekzemplaro/items/09bd10b02ecbb35c0efa]]
-[[reportlabのplatypusを使ってtableを描画するサンプル。wrapOnを呼びなさいということ &#183; GitHub:https://gist.github.com/bgnori/4452571]]

で、この辺が使えそう。

 # reportlab platypus Tableを使う例
 # reportlab の Table の表示位置をコントロールする
 # https://qiita.com/ekzemplaro/items/09bd10b02ecbb35c0efa
 
 from reportlab.lib.pagesizes import A4
 from reportlab.lib.styles import getSampleStyleSheet
 from reportlab.lib.units import mm
 from reportlab.lib import colors
 from reportlab.lib.styles import ParagraphStyle
 from reportlab.pdfgen import canvas
 from reportlab.platypus import Image, Paragraph, Table
 from reportlab.pdfbase import pdfmetrics
 #from reportlab.pdfbase.cidfonts import UnicodeCIDFont
 from reportlab.pdfbase.ttfonts import TTFont
 # ------------------------------------------------------------------
 #fontname_g = "HeiseiKakuGo-W5"
 #pdfmetrics.registerFont(UnicodeCIDFont(fontname_g))
 pdfmetrics.registerFont(TTFont('IPAexGothic', 'ipaexg.ttf')) 
 
 cc = canvas.Canvas('example.pdf', pagesize=A4)
 width, height = A4
 
 cc.setFont("IPAexGothic", 16)
 str_out = "こんにちは"
 cc.drawString(100, 730, str_out)
 
 data = [["テスト", 2, 3], ["日本語", 1, 3], [3, 2, 10]]
 
 table = Table(data, colWidths=20*mm)
 table.setStyle([("VALIGN", (0,0), (-1,-1), "MIDDLE"),
                 ("ALIGN", (0,0), (-1,-1), "CENTER"),
                 ('INNERGRID', (0,0), (-1,-1), 0.25, colors.black),
         ('BOX', (0, 0), (-1, -1), 0.25, colors.black),
 #        ('FONT', (0, 0), (-1, -1), "HeiseiKakuGo-W5", 16),
         ('FONT', (0, 0), (-1, -1), "IPAexGothic", 16),
         ])
 #
 table.wrapOn(cc, width, height)
 #
 table.drawOn(cc, 140*mm, 250*mm)
 table.drawOn(cc, 75*mm, 225*mm)
 table.drawOn(cc, 10*mm, 200*mm)
 #
 styles = getSampleStyleSheet()
 my_style = styles["Normal"]
 my_style.name = "bonlife"
 #my_style.fontName = "HeiseiKakuGo-W5"
 my_style.fontName = "IPAexGothic"
 my_style.fontSize=16
 
 ptext = "これはサンプルです。"
 pp = Paragraph(ptext, style=my_style)
 pp.wrapOn(cc, 70*mm, 50*mm)  # size of 'textbox' for linebreaks etc.
 pp.drawOn(cc, 50*mm, 190*mm)    # position of text / where to draw
 
 cc.showPage()
 cc.save()
 print('complete')

と、もっと簡易版で

 # reportlab platypus Tableを使う例
 # reportlabのplatypusを使ってtableを描画するサンプル。wrapOnを呼びなさいということ
 #https://gist.github.com/bgnori/4452571
    
 from reportlab.pdfgen import canvas
 from reportlab.lib.pagesizes import A4
 from reportlab.lib.units import mm
 
 from reportlab.pdfbase import pdfmetrics
 from reportlab.pdfbase.ttfonts import TTFont
 
 from reportlab.lib import colors
 from reportlab.platypus import Table
 
 #pdfmetrics.registerFont(TTFont('IPA Gothic',
 #    '/usr/share/fonts/ipa-gothic/ipag.ttf'))
 pdfmetrics.registerFont(TTFont('IPAexGothic', 'ipaexg.ttf'))
 
 xmargin = 8.4*mm
 ymargin = 8.8*mm
 swidth = 48.3*mm
 sheight = 25.4*mm
 
 c = canvas.Canvas('example2.pdf', pagesize=A4)
 
 #c.drawString(xmargin, ymargin, u"どや、pdfやで。reportlab!")
 
 t = Table([['a', 'b'], ['1', '2']])
 #t.setStyle([('TEXTCOLOR', (0,0), (1,0), colors.red)])  # 元サンプルではこうしている
 t.setStyle([('INNERGRID', (0,0), (-1,-1), 0.25, colors.black), # 罫線、上のサンプルから借用
         ('BOX', (0, 0), (-1, -1), 0.25, colors.black),
         ('FONT', (0, 0), (-1, -1), "IPAexGothic", 16),
         ])
 
 t.wrapOn(c, 100*mm, 100*mm)
 
 t.drawOn(c, 100*mm, 100*mm)
 c.showPage()
 c.save()
 print('complete')



〜〜〜〜〜〜〜〜〜〜〜〜
**おまけ jupyter notebookのセルの幅を広げたいとき [#sf79a41c]
[[Jupyter Notebookのセル幅を広げたい! - Qiita:https://qiita.com/rinascimento741/items/a884514a75dfcdb310ac]] がよさそう

 pip install jupyterthemes
 
 jt -cellw 95%

または、~
[[IPython/Jupyter Notebook enlarge/change cell width &#183; GitHub:https://gist.github.com/paulochf/f6c9ed0b39f85dd85270]]

custom.css で
 
 .container {
     width: 99% !important;
 }   
 
 div.cell.selected {
     border-left-width: 1px !important;	
 }
 
 div.output_scroll {
     resize: vertical !important;
 }
で、Jupyter Notebookの再起動が必要らしい。

**おまけ 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

**おまけ linux上のunzipで漢字コード名の文字コードをWindows(SJIS)からLinux(UTF-8)へ変換する [#vb243d83]
 unzip -O sjis foo.zip
これによって、内蔵されるファイルの名前をSJISからUTF-8に変換できる。

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