技術メモ

役に立てる技術的な何か、時々自分用の覚書。幅広く色々なことに興味があります。

リスト内を検索して該当するインデックスを全て返す (python)

a = [1,2,3,2,3,4,5,4,3,2,1]

こんなデータがあった時、3がある場所を取ってきたいとする。

a.index(3)
# 2

とすると最初のインデックスだけが返ってくる。
希望は全てを取ってくることなので、これではダメ。
じゃあどうするか。

index = []
for i,j in enumerate(a):
    if j==3:
        index.append(i)
# index:[2,4,8]

numpyを使うともっときれいに書ける。そのうえ、巨大なリストだとより高速。

import numpy as np
a = np.array(a)
np.where(a==3)
# array([2,4,8], dtype=int64)

関連記事

AlphaGOの自己対戦棋譜のsgfファイル取得

有志によるSGFファイル

https://s3-us-west-1.amazonaws.com/apetresc-site/alphago_selfplay.zip
(ソース:apetresc comments on AG vs AG Games 11 through 20 now available

コピペ用

wget https://s3-us-west-1.amazonaws.com/apetresc-site/alphago_selfplay.zip
unzip alphago_selfplay.zip


**公式サイト:
https://deepmind.com/research/alphago/alphago-vs-alphago-self-play-games/
公式サイトでは直接sgfファイルを入手出来ないが、UIを使って見られるようになっている

SGF Viewer
ここでAlphaGOの自己対戦棋譜が一部閲覧できるようになっている。

pandasで重複数をカウントする

pandasで重複数をカウントしたい時、
例えばこんなデータがあったとする。

import pandas as pd
 
df = pd.DataFrame([['AA',100],['AA',200],['AA',200],
                  ['BB',100],['BB',200]],columns=['x','y'])
#---------------
#     x    y
# 0  AA  100
# 1  AA  200  
# 2  AA  200  
# 3  BB  100
# 4  BB  200
#-----------------

xの列はAAが3つBBが2つある。
これを

a = {"AA":3, "BB":2}

のように表現したい。

for文を使ってなんとかする方法は一つある。

a = dict()
for index, row in df.iterrows():
    if a.has_key(row["x"]):
        a[row["x"]] += 1
    else:
        a[row["x"]] = 1
#In : a
#Out: {'AA': 3, 'BB': 2}

しかしこれでは、行数が大きくなってくると時間がかかってしまう。
実はpandasではこれを高速で行う方法がある。
applyという関数を使う方法だ。

a = dict()
def b(i):
    if a.has_key(i):
        a[i] += 1
    else:
        a[i] = 1
df["x"].apply(lambda x:b(x))
#In : a
#Out: {'AA': 3, 'BB': 2}

これで高速に重複カウントができる。



参考サイト:
DataFrame や Series の重複データをチェック・削除-python | コード7区
Python pandas データのイテレーションと関数適用、pipe - StatsFragments