Pandas - 创建类似于pd.get_dummies的多个列

时间:2016-09-07 18:49:40

标签: python pandas dataframe

让我们说我的数据如下:

df = pd.DataFrame({'color': ['red', 'blue', 'green', 'red', 'blue', 'blue'], 'line': ['sunday', 'sunday', 'monday', 'monday', 'monday', 'tuesday'],
               'group': ['1', '1', '2', '1', '1', '1'], 'value': ['a', 'b', 'a', 'c', 'a', 'b']})

    color   group   line    value
0   red       1     sunday   a
1   blue      1     sunday   b
2   green     2     monday   a
3   red       1     monday   c
4   blue      1     monday   a
5   blue      1    tuesday   b

基本上,我想要的是获得每种颜色的行列表。例如,我希望颜色为红色,以在其自己的列中显示与其关联的每一行和值。诀窍是我还想显示与同一组颜色相关的其他线条。相应的值将不符合条件'。因此我希望我的输出看起来像这样:

    color   line_1  line_1_value    line_2  line_2_value    line_3     line_3_value
0   red     sunday       a          monday       c          tuesday    not eligible
1   blue    sunday       b          monday       a          tuesday         b
2   green   monday       c      

有大约50,000种独特的颜色'我需要这样做。我确定它相对简单,但我还没有掌握所需的知识或技能。任何帮助,将不胜感激!

2 个答案:

答案 0 :(得分:0)

删除不需要的列并添加一列以获得每种颜色的唯一子索引:

df = df.drop('group', axis=1)
df['index_by_color'] = df.groupby('color').cumcount()

   color     line value  index_by_color
0    red   sunday     a               0
1   blue   sunday     b               0
2  green   monday     a               0
3    red   monday     c               1
4   blue   monday     a               1
5   blue  tuesday     b               2

使用pivot_table获取所需数据的方向:

df.pivot_table(index='color', columns=['index_by_color'], aggfunc=lambda x:x.iloc[0])

                  line                  value
index_by_color       0       1        2     0     1     2
color
blue            sunday  monday  tuesday     b     a     b
green           monday    None     None     a  None  None
red             sunday  monday     None     a     c  None

关于aggfunc=lambda x:x.iloc[0]的事情是将非数字轮转数据减少为特定值,并且子帧的第一个元素足以满足数据结构的唯一性。

重新排列列分层索引:

 res = res.sort_index(axis=1, level=1)

                  line value    line value     line value
index_by_color       0     0       1     1        2     2
color
blue            sunday     b  monday     a  tuesday     b
green           monday     a    None  None     None  None
red             sunday     a  monday     c     None  None

根据您需要的确切演示文稿,其余部分是微不足道的清理,例如cumcount()+1如果您需要从1开始编号而不是0,请根据需要写入/展平列名称res.columns =['_'.join([l0, str(l1)]) for l0,l1 in res.columns]或等价物等。

答案 1 :(得分:0)

考虑使用列名处理在两个透视dfs上进行合并:

df['count'] = df.groupby('color').cumcount() + 1

pvt1 = df.pivot(columns='count', index='color', values='line').reset_index().fillna('')
pvt1.columns = ['color'] + ['line_'+str(c) for c in pvt1.columns[1:]]

pvt2 = df.pivot(columns='count', index='color', values='value').reset_index().fillna('')
pvt2.columns = ['color'] + ['line_'+str(c)+'_value' for c in pvt2.columns[1:]]

pvtdf = pd.merge(pvt1, pvt2, on=['color'])
pvtdf = pvtdf[[c for c in sorted(pvtdf.columns)]]

#    color  line_1 line_1_value  line_2 line_2_value   line_3 line_3_value
# 0   blue  sunday            b  monday            a  tuesday            b
# 1  green  monday            a                                           
# 2    red  sunday            a  monday            c