2017-08-27 10 views
2

私のpandasデータフレームの列の1つにリストが含まれています。 そして、私はそれを展開し、以下のような垂直の形状に変換したいと思います。 どうすればいいですか? (コード)の前縦の列にリストを変換するには?

:(テーブル)の前

import pandas as pd 
pd.DataFrame({ 
    'col1':['fruit', 'veicle', 'animal'], 
    'col2':['apple', 'bycicle', 'cat'], 
    'col3':[1,4,2], 
    'list':[ 
     [10, 20], 
     [1.2, 3.0, 2.75], 
     ['tommy', 'tom'] 
    ] 
}) 

|col1 |col2 |col3|list | 
    |------|-------|----|-------| 
    |fruit |apple | 1|10  | 
    |fruit |apple | 1|20  | 
    |viecle|bycicle| 4|1.2 | 
    |viecle|bycicle| 4|3.0 | 
    |viecle|bycicle| 4|2.75 | 
    |animal|cat | 2|'tommy'| 
    |animal|cat | 2|'tom | 

|col1 |col2 |col3|list   | 
    |------|-------|----|----------------| 
    |fruit |apple | 1|[10, 20]  | 
    |veicle|bicycle| 4|[1.2, 3.0, 2.75]| 
    |animal|cat | 2|['tommy', 'tom']| 

注1:リストの長さと種類が異なります。

注2:NOT datafarmeを生成するコードを変更してください。

ありがとうございます。

+0

[パンダで異なる長さでリストを爆発]の可能複製(https://stackoverflow.com/questions/45885143/ explod-lists-with-different-lengths-in-pandas) – Wen

+0

あなたは単にGoogleにそれを尋ねる前に、https://stackoverflow.com/questions/45885143/explode-lists-with-different-lengths-in-pandas/45886206 #45886206 – Wen

+0

役に立つリンクをありがとう、重複した質問を投稿してくれてありがとうございます。 Googleで慎重に検索しましたが、その記事が見つかりませんでした。 – AkiraIsaka

答えて

3

np.repeatnp.concatenateを使用して、他の日PIRからこのクールなトリックを学んだ:

idx = np.arange(len(df)).repeat(df.list.str.len(), 0)  
out = df.iloc[idx, :-1].assign(list=np.concatenate(df.list.values)) 
print(out) 

    col1  col2 col3 list 
0 fruit apple  1  10 
0 fruit apple  1  20 
1 veicle bycicle  4 1.2 
1 veicle bycicle  4 3.0 
1 veicle bycicle  4 2.75 
2 animal  cat  2 tommy 
2 animal  cat  2 tom 

パフォーマンス

# Bharath 
%timeit df.set_index(['col1','col2','col3']['list'].apply(pd.Series).stack()\ 
       .reset_index().drop('level_3',axis=1) 
100 loops, best of 3: 7.75 ms per loop 

# Mine 
%%timeit 
idx = np.arange(len(df)).repeat(df.list.str.len(), 0)  
out = df.iloc[idx, :-1].assign(list=np.concatenate(df.list.values))  
1000 loops, best of 3: 1.41 ms per loop 

つのライナーとして
df_test = pd.concat([df] * 10000) 

# Bharath 
%timeit df_test.set_index(['col1','col2','col3'])['list'].apply(pd.Series).stack()\ 
       .reset_index().drop('level_3',axis=1) 
1 loop, best of 3: 7.09 s per loop 

# Mine 
%%timeit 
idx = np.arange(len(df_test)).repeat(df_test.list.str.len(), 0)  
out = df_test.iloc[idx, :-1].assign(list=np.concatenate(df_test.list.values)) 
10 loops, best of 3: 123 ms per loop 

、バーラトの答えは短いが、遅いです。

idx = df.set_index(['col1', 'col2', 'col3']).index 
out = pd.DataFrame(df.list.values.tolist(), index=idx).stack()\ 
       .reset_index().drop('level_3', 1).rename(columns={0 : 'list'}) 

print(out) 

    col1  col2 col3 list 
0 fruit apple  1  10 
1 fruit apple  1  20 
2 veicle bycicle  4 1.2 
3 veicle bycicle  4  3 
4 veicle bycicle  4 2.75 
5 animal  cat  2 tommy 
6 animal  cat  2 tom 

100 loops, best of 3: 4.7 ms per loop 

10 loops, best of 3: 28.9 ms per loop 
+0

Numpyは非常に高速です。それは難しい答えを打つのは難しい。 – Dark

+0

@Bharathshettyはい、私はパンダがこれほど遅いとは期待していませんでした。 –

+0

私は適用を使用しました。そう、その少し遅い。私は適用が常にパフォーマンスのビットを殺すと思う。 – Dark

5
あなたが最初の3つの列set_indexでき

と:ここでは、大規模なデータの200倍高速化のためのデータフレームのコンストラクタの代わりdf.applyを使用して改善がありますリストの列にpd.Seriesを適用し、それらをスタックします。

df.set_index(['col1','col2','col3'])['list'].apply(pd.Series).stack().reset_index().drop('level_3',axis=1) 

出力:

 
    col1  col2 col3  0 
0 fruit apple 1  10 
1 fruit apple 1  20 
2 veicle bycicle 4  1.2 
3 veicle bycicle 4  3  
4 veicle bycicle 4  2.75 
5 animal cat  2  tommy 
6 animal cat  2  tom 
+1

タイミングを追加:https://stackoverflow.com/a/45906100/4909087 –

0

ここでは、このタスクを実行する方法を大まかにです。これは厳密解ではなく、あなたのタスクを達成する方法のアイデアを与えるだろう。

original_df = <your dataframe to start> 
new_empty_df = pd.DataFrame() 
# now go through each row of the original df 
for i in range(original_df.shape[0]): 
    row_Series = original_df.iloc[i] 
    row_list = row_Series['list'] 
    for item in row_list: 
     new_empty_df.append({'col1':row_Series['col1'], 
           'col2':row_Series['col2'], 
           'list':item}) 
関連する問題