1. ホーム
  2. パイソン

[解決済み】pandas dataframeの文字列エントリーを分割(explode)して別の行にする。

2022-04-15 16:05:26

質問

私は pandas dataframe には、カンマで区切られた値を含むテキスト文字列が1列あります。CSV の各フィールドを分割し、エントリごとに新しい行を作成したいと思います (CSV はきれいで、',' で分割する必要があるだけだと仮定します)。例えば a は次のようになります。 b :

In [7]: a
Out[7]: 
    var1  var2
0  a,b,c     1
1  d,e,f     2

In [8]: b
Out[8]: 
  var1  var2
0    a     1
1    b     1
2    c     1
3    d     2
4    e     2
5    f     2

これまで、いろいろと簡単な関数を試してみましたが .apply メソッドは、軸で使用した場合、戻り値として1行しか受け取らないようです。 .transform を動作させることができます。何か提案があれば、ぜひお願いします。

データ例です。

from pandas import DataFrame
import numpy as np
a = DataFrame([{'var1': 'a,b,c', 'var2': 1},
               {'var1': 'd,e,f', 'var2': 2}])
b = DataFrame([{'var1': 'a', 'var2': 1},
               {'var1': 'b', 'var2': 1},
               {'var1': 'c', 'var2': 1},
               {'var1': 'd', 'var2': 2},
               {'var1': 'e', 'var2': 2},
               {'var1': 'f', 'var2': 2}])

numpyを経由することでDataFrameのメタデータが失われるため、うまくいかないことは分かっていますが、私が何をしようとしたかを感じ取ってもらえるはずです。

def fun(row):
    letters = row['var1']
    letters = letters.split(',')
    out = np.array([row] * len(letters))
    out['var1'] = letters
a['idx'] = range(a.shape[0])
z = a.groupby('idx')
z.transform(fun)

解決方法は?

こんなのはどうでしょう。

In [55]: pd.concat([Series(row['var2'], row['var1'].split(','))              
                    for _, row in a.iterrows()]).reset_index()
Out[55]: 
  index  0
0     a  1
1     b  1
2     c  1
3     d  2
4     e  2
5     f  2

そして、カラムの名前を変更するだけです。