groupby / unstack on column name

时间:2016-08-09 14:43:48

标签: python pandas

我有一个具有以下结构的数据框

    idx  value  Formula_name
0   123456789     100     Frequency No4
1   123456789     150     Frequency No25
2   123456789     125     Frequency No27
3   123456789     0.2     Power Level No4
4   123456789     0.5     Power Level No25
5   123456789     -1.0    Power Level No27
6   123456789     32      SNR  No4
7   123456789     35      SNR  No25
8   123456789     37      SNR  No27
9   111222333     ...

因此,将频率与其对应度量相关联的唯一方法是通过频率的数量。我知道可能的范围(从25到200步的100到200 MHz),但不知道数据中出现的频率(或数量),也不知道用“频率”将频率与度量相关联的“数字”。

我想找到类似的数据框:

                  SNR                        Power Level
    idx           100   125  150   175  200  100  125  150 175 200
0   123456789     32    37   35    NaN  NaN  0.2  -1.0 0.5 NaN NaN
1   111222333     ...

对于只有一个指标,我创建了两个数据帧,一个包含频率,一个包含指标,并在数字上合并:

     idx         Formula_x  value_x number   Formula_y  value_y
0    123456789   SNR        32      4        frequency  100
1    123456789   SNR        35      25       frequency  150

然后我会将数据帧取消堆叠:

df.groupby(['idx','value_y']).first()[['value_x']].unstack()

这适用于一个指标,但我不知道如何将其应用于更多指标并使用列中的多索引访问它们。

非常欢迎任何想法和建议。

1 个答案:

答案 0 :(得分:2)

您可以使用:

print (df)
         idx  value      Formula_name
0  123456789  100.0     Frequency No4
1  123456789  150.0    Frequency No25
2  123456789  125.0    Frequency No27
3  123456789    0.2   Power Level No4
4  123456789    0.5  Power Level No25
5  123456789   -1.0  Power Level No27
6  123456789   32.0           SNR No4
7  123456789   35.0          SNR No25
8  123456789   37.0          SNR No27

#create new columns from Formula_name
df[['a','b']] = df.Formula_name.str.rsplit(n=1, expand=True)

#maping by Series column b - from No4, No25 to numbers 100,150...
maps = df[df.a == 'Frequency'].set_index('b')['value'].astype(int)
df['b'] = df.b.map(maps)

#remove rows where is Frequency, remove column Formula_name
df1 = df[df.a != 'Frequency'].drop('Formula_name', axis=1)
print (df1)
         idx  value            a    b
3  123456789    0.2  Power Level  100
4  123456789    0.5  Power Level  150
5  123456789   -1.0  Power Level  125
6  123456789   32.0          SNR  100
7  123456789   35.0          SNR  150
8  123456789   37.0          SNR  125

两个解决方案 - unstackpivot_table

df2 = df1.set_index(['idx','a', 'b']).unstack([1,2])
df2.columns = df2.columns.droplevel(0)
df2 = df2.rename_axis(None).rename_axis([None, None], axis=1)
print (df2)
          Power Level             SNR            
                  100  150  125   100   150   125
123456789         0.2  0.5 -1.0  32.0  35.0  37.0

df3 = df1.pivot_table(index='idx', columns=['a','b'], values='value')
df3 = df3.rename_axis(None).rename_axis([None, None], axis=1)
print (df3)
          Power Level             SNR            
                  100  125  150   100   125   150
123456789         0.2 -1.0  0.5  32.0  37.0  35.0