使用Python将列表转换为数据透视表

时间:2014-03-02 12:51:53

标签: python list grouping pivot-table

我有以下格式的列表列表:

listA = [[142L, u'Work Load', [57.35, 19.57]],
[142L, u'Days', [84.0, 44.0]],
[142L, u'Payed', [5684.0, 3944.0]],
[547L, u'Work Load', [87.25, 12.70]],
[547L, u'Days', [98.0, 128.0]],
[547L, u'Payed', [3247.0, 4712.0]],
...]

我希望将其转换为:

listB = [['id', u'Work Load', u'Days', u'Payed'],
[142L, 57.35, 84.0, 5684.0],
[142L, 19.57, 44.0, 3944.0],
[547L, 87.25, 98.0, 3247.0],
[547L, 12.70, 128.0, 4712.0],
...]

我如何分组?我这样做的原因是因为我试图将列表导出到csv。 有任何想法吗?谢谢!

3 个答案:

答案 0 :(得分:2)

由于您展示的列表按“id”排序,因此您可以直接使用itertools.groupbyzip

In [189]: lst  #if not sorted, lst.sort(key=lambda x: x[0]) first
Out[189]: 
[[142L, u'Work Load', [57.35, 19.57]],
 [142L, u'Days', [84.0, 44.0]],
 [142L, u'Payed', [5684.0, 3944.0]],
 [547L, u'Work Load', [87.25, 12.7]],
 [547L, u'Days', [98.0, 128.0]],
 [547L, u'Payed', [3247.0, 4712.0]]]

In [190]: lstB=[['id', u'Work Load', u'Days', u'Payed'],]
     ...: for k, g in itertools.groupby(lst, lambda x: x[0]):
     ...:     t=zip(*(i[-1] for i in g))
     ...:     for i in t:
     ...:         lstB.append([k]+list(i))

#outputs:
In [587]: lstB
Out[587]: 
[['id', u'Work Load', u'Days', u'Payed'],
 [142L, 57.35, 84.0, 5684.0],
 [142L, 19.57, 44.0, 3944.0],
 [547L, 87.25, 98.0, 3247.0],
 [547L, 12.7, 128.0, 4712.0]]

答案 1 :(得分:1)

使用pandas

import pandas as pd

listA = [[142L, u'Work Load', [57.35, 19.57]],
[142L, u'Days', [84.0, 44.0]],
[142L, u'Payed', [5684.0, 3944.0]],
[547L, u'Work Load', [87.25, 12.70]],
[547L, u'Days', [98.0, 128.0]],
[547L, u'Payed', [3247.0, 4712.0]]]

dfA = pd.DataFrame(listA)
dfA.columns = ['id','field','data']

dfB = dfA.groupby('id').apply(
    lambda grp: pd.DataFrame(zip(*grp['data']), columns=grp['field']))
dfB.index = dfB.index.droplevel(-1)
print(dfB)

产生DataFrame

field  Work Load  Days  Payed
id                           
142        57.35    84   5684
142        19.57    44   3944
547        87.25    98   3247
547        12.70   128   4712

然后,您可以使用

将DataFrame写入CSV
dfB.to_csv('/tmp/test.csv', sep=',')

看起来像这样:

id,Work Load,Days,Payed
142,57.35,84.0,5684.0
142,19.57,44.0,3944.0
547,87.25,98.0,3247.0
547,12.7,128.0,4712.0

答案 2 :(得分:0)

这是解决我问题的有效方法:

    import pandas as pd
    dt = [[142L, u'Work Load', [57.35, 19.57]],
          [142L, u'Days', [84.0, 44.0]],
          [142L, u'Payed', [5684.0, 3944.0]],
          [547L, u'Work Load', [87.25, 12.70]],
          [547L, u'Days', [98.0, 128.0]],
          [547L, u'Payed', [3247.0, 4712.0]]]
    dfA = pd.DataFrame(dt)
    dfA.columns = [u'id','field','data']
    dfB = dfA.groupby(u'id').apply(
        lambda grp: pd.DataFrame(zip(*grp['data']), columns=grp['field']))
    dfB.index = dfB.index.droplevel(-1)
    data = StringIO()
    dfB.to_csv(data, sep=';', encoding='utf-8')
    self.response = HttpResponse(data.getvalue(), mimetype='text/csv')
    self.add_response_headers()
    self.response.close()
    self.response.flush()
    return self.response

感谢您的帮助。