pandasでタグの集計をする(列にリストを含む場合の集計処理)

例えばQiitaもそうですが、記事ごとに複数のタグが割り当てられていることが多々あります(この記事だとPython, pandas, データ分析など)。

これらタグは可変長の属性になりやすく、リストや","で区切って一つの文字列として列に収められていることが多いことでしょう。

この記事では、上記のような構造を持ったデータに対して、タグで集計処理をしたい場合の処理について楽が出来るようになる方法を共有したいと思います。

具体的には、以下のようなデータを"変換後"のような新しい構造にしたデータフレームを作成します。

import pandas as pd

import numpy as np

df = pd.DataFrame({'name':['aaa', 'bbb', 'ccc'], 'tag':[['X', 'Z'], ['Y'], ['Y', 'Z']]})

変換前(df)

name
tag

0
aaa
[X, Z]

1
bbb
[Y]

2
ccc
[Y, Z]

変換後

name
tag

0
aaa
X

1
aaa
Z

2
bbb
Y

3
ccc
Y

4
ccc
Z


結論

次の関数をコピペして使ってみてください。


def flatten_col(df, key, col):
df = df.dropna(subset=[col])
k = np.repeat(df[key],df[col].apply(len)).reset_index(drop=True)
c = np.concatenate(df[col].values)
return pd.DataFrame({key:k, col:c})


使用例


dff = flatten_col(df, 'name', 'tag')

dff

name
tag

0
aaa
X

1
aaa
Z

2
bbb
Y

3
ccc
Y

4
ccc
Z


import seaborn as sns
sns.countplot(x="tag", data=dff)

output.png

このようにseabornのcountplotに渡してあげれば簡単に集計結果が得られます。


おわりに


  • もし他にちゃんとした方法を御存知の方は教えていただければ幸いです

  • この記事のタイトルとflatten_col()の関数名に納得してない…w