4

私は次のデータフレームを持っています

In[45]: data[:10]  
Out[45]:
   Z    A    beta2    M      shell
0  100  200  0.3112   197.2 -4.213
1  100  200 -0.4197   202   -1.143
2  100  200  0.03205  203    0    
3  100  201  0.2967   191   -4.434
4  100  201 -0.4893   196.1 -4.691
5  100  202  0.3084   183.4 -4.134
6  100  202 -0.4873   188.2 -4.75 
7  100  202 -0.2483   188.4 -1.106
8  100  203  0.3069   177.1 -4.355
9  101  203 -0.4956   182.5 -5.217

私の質問は、データが一意でないことを考慮して、インデックス(またはMultiIndexes)として(Z、A)を持つMultiIndexを持つようにデータをグループ化/変換するにはどうすればよいですか?私の目標をクリアするために、これは私が達成することを期待していることです:

             beta2[1] beta2[2]  beta2[3]   M[1]   M[2]   M[3]   shell[1]   shell[2]  shell[3]
   Z    A 
0  100  200  0.3112   -0.4197   0.03205    197.2  202    203    -4.213     -1.143    0
1  100  201  0.2967   0.4893    NaN        191    196.1  NaN    -4.434     -4.691    NaN
2  100  202  0.3084   -0.4873   NaN        183.4  188.2  NaN    -4.134     -4.75     NaN
3  100  203  0.3069   NaN       NaN        177.1  NaN    NaN    -4.355     NaN       NaN 
4  101  203  -0.4956  NaN       NaN        182.5  NaN    NaN    -5.217     NaN       NaN

これには少なくとも2つのステップが含まれることを理解しています。1つは一意性のため、もう1つはZ、Aでのインデックス作成のためです。したがって、これらのステップの1つで助けがあれば幸いです。また、この問題により適したデータ構造はありますか?

編集:私は次の行を見つけました:

data = data.set_index(('Z'、'A'))

Z、Aのインデックス作成の問題を解決します。残念ながら、これは(Z、A)ペアが一意である場合にのみ機能します。

4

1 に答える 1

6

私はこれらのような問題に取り組むための未解決の問題を抱えています:

https://github.com/pydata/pandas/issues/388

これが解決策です。まず、グループの序数を取得するための単純な(そしてあまり効率的ではない)関数:

def group_position(*args):
    """
    Get group position
    """
    from collections import defaultdict
    table = defaultdict(int)

    result = []
    for tup in zip(*args):
        result.append(table[tup])
        table[tup] += 1

    return np.array(result)

すなわち

In [49]: group_position(df['Z'], df['A'])
Out[49]: array([0, 1, 2, 0, 1, 0, 1, 2, 0, 0])

これを補助インデックス変数として使用し、スタックを解除します。

In [52]: df
Out[52]: 
     Z    A    beta2      M  shell
0  100  200  0.31120  197.2 -4.213
1  100  200 -0.41970  202.0 -1.143
2  100  200  0.03205  203.0  0.000
3  100  201  0.29670  191.0 -4.434
4  100  201 -0.48930  196.1 -4.691
5  100  202  0.30840  183.4 -4.134
6  100  202 -0.48730  188.2 -4.750
7  100  202 -0.24830  188.4 -1.106
8  100  203  0.30690  177.1 -4.355
9  101  203 -0.49560  182.5 -5.217

In [53]: df['pos'] = group_position(df['Z'], df['A'])

In [54]: df.set_index(['Z', 'A', 'pos']).unstack('pos')
Out[54]: 
          beta2                       M                shell              
pos           0       1        2      0      1      2      0      1      2
Z   A                                                                     
100 200  0.3112 -0.4197  0.03205  197.2  202.0  203.0 -4.213 -1.143  0.000
    201  0.2967 -0.4893      NaN  191.0  196.1    NaN -4.434 -4.691    NaN
    202  0.3084 -0.4873 -0.24830  183.4  188.2  188.4 -4.134 -4.750 -1.106
    203  0.3069     NaN      NaN  177.1    NaN    NaN -4.355    NaN    NaN
101 203 -0.4956     NaN      NaN  182.5    NaN    NaN -5.217    NaN    NaN

あなたが示したのとまったく同じようにそれを取得するための最終的な変更:

In [61]: result = df.set_index(['Z', 'A', 'pos']).unstack('pos')

In [62]: result.rename(columns=lambda x: '%s[%d]' % (x[0], x[1]+1)).reset_index()
Out[62]: 
     Z    A  beta2[1]  beta2[2]  beta2[3]   M[1]   M[2]   M[3]  shell[1]  shell[2]  shell[3]
0  100  200    0.3112   -0.4197   0.03205  197.2  202.0  203.0    -4.213    -1.143     0.000
1  100  201    0.2967   -0.4893       NaN  191.0  196.1    NaN    -4.434    -4.691       NaN
2  100  202    0.3084   -0.4873  -0.24830  183.4  188.2  188.4    -4.134    -4.750    -1.106
3  100  203    0.3069       NaN       NaN  177.1    NaN    NaN    -4.355       NaN       NaN
4  101  203   -0.4956       NaN       NaN  182.5    NaN    NaN    -5.217       NaN       NaN
于 2012-04-13T22:40:25.460 に答える