2017-07-07 6 views
4

私はこのようなパンダのデータフレームを持っている:パンダ:セルに列のペアを変換

ts | thing_0 | qty_0 | thing_1 | qty_1 | thing_2 | qty_2 
-------------------------------------------------------- 
1 | dog  |  5 | cat  |  3 | mouse |  1 
2 | house |  6 | dog  |  4 | cat  |  2 
... 

私はthing sが列になって、qty sは、セルの値になるような方法でこれを変換したいです。このように:

ts | dog | cat | mouse | house 
------------------------------ 
1 | 5 | 3 |  1 |  0 
2 | 4 | 2 |  0 |  6 
... 

現在、私は手動でdf.values配列を反復して手動でこの変換をやっているが、これは非常に遅いです。パンダの手段でこれを実現するより速い方法がありますか?

私はdf.pivotを見たことがありますが、thing_0との関係を説明する方法が見つかりませんでした。

答えて

3

あなたはstr.splitによって、列からMultiIndexを作成することができ、その後stackunstackによって再構築:

df = df.set_index('ts') 
df.columns = df.columns.str.split('_', expand=True) 
df = df.stack().reset_index(level=1, drop=True) 
     .set_index('thing', append=True)['qty'].unstack(fill_value=0) 
print (df) 
thing cat dog house mouse 
ts       
1  3 5  0  1 
2  2 4  6  0 

代わりunstackpivotのもう一つの解決策:

df = df.set_index('ts') 
df.columns = df.columns.str.split('_', expand=True) 
df = df.stack().reset_index() 
df = df.pivot(index='ts', columns='thing', values='qty').fillna(0).astype(int) 
print (df) 
thing cat dog house mouse 
ts       
1  3 5  0  1 
2  2 4  6  0 

そして第三ソリューション - 動的lreshapeのための辞書を作成しますunstack

-の

お知らせ列はdf = df.sort_index(axis=1)

t = [x for x in df.columns if x.startswith('thing')] 
q = [x for x in df.columns if x.startswith('qty')] 
df = pd.lreshape(df, {'thing':t, 'qty':q}) 
     .set_index(['ts','thing'])['qty'].unstack(fill_value=0) 

print (df) 
thing cat dog house mouse 
ts       
1  3 5  0  1 
2  2 4  6  0 

EDIT追加しない場合は、ソートする必要があります:

lreshapeは現在文書化されていないが、しかしによって(with pd.wide_to_long too)削除されます将来的には可能です。

考えられる解決策は3つの機能すべてを1つにマージすることです - おそらくmeltですが、今は実装されていません。たぶん新しいバージョンのパンダで。その後、私の答えは更新されます。

4

あなたがthingqty列合体するlreshapeを使用することができます。

import pandas as pd 

df = pd.DataFrame({'qty_0': [5, 6], 'qty_1': [3, 4], 'qty_2': [1, 2], 'thing_0': ['dog', 'house'], 'thing_1': ['cat', 'dog'], 'thing_2': ['mouse', 'cat'], 'ts': [1, 2]}) 

reshaped = pd.lreshape(df, {'thing':['thing_0','thing_1','thing_2',], 
          'qty':['qty_0','qty_1','qty_2']}) 

result = reshaped.pivot(index='ts', columns='thing', values='qty') 
print(result) 

利回り

thing cat dog house mouse 
ts       
1  3.0 5.0 0.0 1.0 
2  2.0 4.0 6.0 0.0 

:希望のデータフレームを作成するために、次に

In [10]: pd.lreshape(df, {'thing':['thing_0','thing_1','thing_2',], 'qty':['qty_0','qty_1','qty_2']}) 
Out[10]: 
    ts thing qty 
0 1 dog 5 
1 2 house 6 
2 1 cat 3 
3 2 dog 4 
4 1 mouse 1 
5 2 cat 2 

pivot

私はjezrael's solutionが合体したい列名の規則性を利用するので、より良いと思います。 df.columns.str.split('_', expand=True)あなたが を合体したい列名が不規則な状況で役に立つかもしれません

{'thing':['thing_0','thing_1','thing_2',], 
'qty':['qty_0','qty_1','qty_2']} 

lreshapeよりも一般的かつより少ない反復です。

関連する問題