Pandasでは実はlistもDataFrameの要素にできる(+explode)

2024/10/10に公開

こんにちは、沙代です。
DataFrameで1行を複数行に展開しようとした時に、実はpandasは文字列数値だけでなく、listも要素にできることに気づきました。

環境
MacOS Montery 12.6.2 (M1 Pro)
Python 3.9.1
pandas 2.2.3

確認用コード

example1.py
import pandas as pd
df = pd.DataFrame({"A": [[1,2,3],"hello", [4,5]], "B": [1,2,3]})
print(df)
print(df.dtypes)
print()
print(df["A"][0])
print(df["A"][0][2])
output
           A  B
0  [1, 2, 3]  1
1      hello  2
2     [4, 5]  3
A    object
B     int64
dtype: object

[1, 2, 3]
3

もうちょっというと、dictもsetもなんでも大丈夫なようです。

df = pd.DataFrame({"A": [{"k": {"v", "vv", "vvv"}}]})
print(df)
output
                           A
0  {'k': {'vv', 'vvv', 'v'}}

applyから生成してみる

applyから生成してみます。

examle_apply.py
import pandas as pd
df = pd.DataFrame({"A": ["hello", "sayo"]})
df.loc[:, "B"] = df["A"].apply(lambda x: list(x))
print(df)
output
       A                B
0  hello  [h, e, l, l, o]
1   sayo     [s, a, y, o]

listを複数行に展開してみる。

df.explode()を使って複数行に展開してみます。(document)

example_explode1.py
df = pd.DataFrame({"A": ["hello", "sayo"]})
df.loc[:, "B"] = df["A"].apply(lambda x: list(x))
print(df.explode("B"))
output
       A  B
0  hello  h
0  hello  e
0  hello  l
0  hello  l
0  hello  o
1   sayo  s
1   sayo  a
1   sayo  y
1   sayo  o

indexを貼り直して欲しい場合は、ignore_indexオプションを使います。

example_explode2.py
df = pd.DataFrame({"A": ["hello", "sayo"]})
df.loc[:, "B"] = df["A"].apply(lambda x: list(x))
print(df.explode("B", ignore_index=True))
output
       A  B
0  hello  h
1  hello  e
2  hello  l
3  hello  l
4  hello  o
5   sayo  s
6   sayo  a
7   sayo  y
8   sayo  o

explodeのおまけ

基本は、Series.explodeかもしれません。(document)

example_ser.py
s = pd.Series([[1, 2, 3], 'foo', [], [3, 4]])
s.explode()
output
0      1
0      2
0      3
1    foo
2    NaN
3      3
3      4
dtype: object

参考にさせていただいたページ

https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.explode.html
https://pandas.pydata.org/docs/reference/api/pandas.Series.explode.html

Discussion