2017-08-23 7 views
2

複数のJSONオブジェクトを1つのDataFrameに読み込みます。問題は、列の一部がリストであることです。また、データは非常に大きく、そのためにインターネット上で利用可能なソリューションを使用することはできません。彼らは非常に遅く、メモリ効率の悪いpandas DataFrame内の複数のリスト列を効率よくネスト解除(分解)する

ここでは、私のデータがどのように見えるかです:

df = pd.DataFrame({'A': ['x1','x2','x3', 'x4'], 'B':[['v1','v2'],['v3','v4'],['v5','v6'],['v7','v8']], 'C':[['c1','c2'],['c3','c4'],['c5','c6'],['c7','c8']],'D':[['d1','d2'],['d3','d4'],['d5','d6'],['d7','d8']], 'E':[['e1','e2'],['e3','e4'],['e5','e6'],['e7','e8']]}) 
    A  B   C   D   E 
0 x1 [v1, v2] [c1, c2] [d1, d2] [e1, e2] 
1 x2 [v3, v4] [c3, c4] [d3, d4] [e3, e4] 
2 x3 [v5, v6] [c5, c6] [d5, d6] [e5, e6] 
3 x4 [v7, v8] [c7, c8] [d7, d8] [e7, e8] 

そして、これは私のデータの形である:(441079、12)

私の所望の出力は次のようになります。

A  B   C   D   E 
0 x1  v1   c1   d1   e1 
0 x1  v2   c2   d2   e2 
1 x2  v3   c3   d3   e3 
1 x2  v4   c4   d4   e4 
..... 
+2

はい、その後、すべてが遅くなり、メモリは非効率的。このようなデータフレームを決して作成しないことで、この問題はよりよく解決される可能性があります。 –

+0

@ juanpa.arrivillagaこの混乱を起こさないようにJSONファイルを別の方法で読むことはできますか? pd.read_csvにはコンバーターを定義するオプションがありますが、pd.read_jsonに似たものは見つかりません – Moh

+0

可能な重複:https://stackoverflow.com/questions/32468402/how-to-explode-a-list-inside-a-dataframe -cell-into-separate-rows/32470490#32470490 @MohMelを使ってこのメソッドを試しましたか? – Alexander

答えて

3
def explode(df, lst_cols, fill_value=''): 
    # make sure `lst_cols` is a list 
    if lst_cols and not isinstance(lst_cols, list): 
     lst_cols = [lst_cols] 
    # all columns except `lst_cols` 
    idx_cols = df.columns.difference(lst_cols) 

    # calculate lengths of lists 
    lens = df[lst_cols[0]].str.len() 

    if (lens > 0).all(): 
     # ALL lists in cells aren't empty 
     return pd.DataFrame({ 
      col:np.repeat(df[col].values, df[lst_cols[0]].str.len()) 
      for col in idx_cols 
     }).assign(**{col:np.concatenate(df[col].values) for col in lst_cols}) \ 
      .loc[:, df.columns] 
    else: 
     # at least one list in cells is empty 
     return pd.DataFrame({ 
      col:np.repeat(df[col].values, df[lst_cols[0]].str.len()) 
      for col in idx_cols 
     }).assign(**{col:np.concatenate(df[col].values) for col in lst_cols}) \ 
      .append(df.loc[lens==0, idx_cols]).fillna(fill_value) \ 
      .loc[:, df.columns] 

使用法:あなたはPythonの `list`sを含む` object` DTYPE列を持っている場合

In [82]: explode(df, lst_cols=list('BCDE')) 
Out[82]: 
    A B C D E 
0 x1 v1 c1 d1 e1 
1 x1 v2 c2 d2 e2 
2 x2 v3 c3 d3 e3 
3 x2 v4 c4 d4 e4 
4 x3 v5 c5 d5 e5 
5 x3 v6 c6 d6 e6 
6 x4 v7 c7 d7 e7 
7 x4 v8 c8 d8 e8 
+0

私たちはこの問題を抱えています:https://github.com/pandas-dev/pandas/issues/8517#issuecomment-178848365 。テストされている場合は、PRとしても使用されます – Jeff

1

Aの使用​​と残りの列applystack値に関する。このすべてが単一のライナーに凝縮されています。

In [1253]: (df.set_index('A') 
       .apply(lambda x: x.apply(pd.Series).stack()) 
       .reset_index() 
       .drop('level_1', 1)) 
Out[1253]: 
    A B C D E 
0 x1 v1 c1 d1 e1 
1 x1 v2 c2 d2 e2 
2 x2 v3 c3 d3 e3 
3 x2 v4 c4 d4 e4 
4 x3 v5 c5 d5 e5 
5 x3 v6 c6 d6 e6 
6 x4 v7 c7 d7 e7 
7 x4 v8 c8 d8 e8 
+0

私はその単純さのためにこの答えが本当に好きです。私は同様のアプローチで試していましたが、うまく動作しませんでした – Vaishali

関連する問題