如果我有以下格式的数据(存储在pandas数据框中),基本上是一个规范化的类别和商品形式的slu ::
pandas.DataFrame:
categories slug wares
0 [developer, mac, web] alex.payne [macbook-pro, cinema-display, readynas-nv-plus...
1 [mac, musician] jona.bechtolt [audio-kontrol-1, powershot-sd1000, live, mda-...
2 [game, suit, windows] gabe.newell [oa-desk, beyond-tv, windows-xp, office, visua...
3 [developer, mac, software] steven.frank [mac-pro, macbook-air, apple-tv, itunes, addre...
我的意图是绘制与商品相关的类别的图表,我需要以非规范化格式的数据,以某种这样的格式:
categories wares slug
0 developer macbook-pro alex.payne
1 mac macbook-pro alex.payne
2 web macbook-pro alex.payne
3 developer cinema-display alex.payne
4 mac cinema-display alex.payne
5 web cinema-display alex.payne
6 developer readynas-nv-plus alex.payne
将数据从上面的格式转换为下面的数据的最佳方式是什么,最好是利用numpy的内部结构,也很快。
我的方法是相当天真,循环遍历数据框中的每一行,维护一个元组列表,然后将其传递给pandas.DataFrame构造函数。你的任何建议可能会更快更好,所以建议离开!
我也在思考pandas DataFrame中此类数据的替代表示,特别是稀疏矩阵。但我认为这对于groupby查询会更好。如果有其他格式或稀疏矩阵为这种聚合查询提供更好的建议,建议如何去做。
对于那些感兴趣的人来说,这是完整的事情:http://j.mp/lp-usesthis我最终没有像我原先预期的那样进行非规范化,而只是在感兴趣的列上循环。但是任何更好地反规范化的能力都会使它变得更好。
答案 0 :(得分:1)
首先,我强烈建议您不要首先存储这样的数据,pandas并不适用于像列表这样的常规对象。
这是提取数据的一种方法(使用连接,similar to Dan Allen's answer)。
def denormalise(df, *colnames):
df1 = df.copy() # optional, but means we're not changing df globally
cols = [(colname, df1.pop(colname).apply(pd.Series).stack()) for colname in colnames]
for colname, c in cols:
c.index = c.index.droplevel(-1)
c.name = colname
df1 = df1.join(c)
return df1
# optionally .reindex_axis(df.columns, axis=1) # reorder columns
# and .reset_index(drop=True) # 0,1,...n index
使用中:
In [11]: denormalise(df1, 'wares')
Out[11]:
categories slug wares
0 [developer, mac, web] alex.payne macbook-pro
0 [developer, mac, web] alex.payne cinema-display
0 [developer, mac, web] alex.payne readynas-nv-plus
1 [mac, musician] jona.bechtolt audio-kontrol-1
1 [mac, musician] jona.bechtolt powershot-sd1000
1 [mac, musician] jona.bechtolt live
Pandas允许您将其添加为DataFrame方法以方便:
In [12]: pd.DataFrame.denormalise = denormalise
In [13]: df1.denormalise('wares', 'categories')
Out[13]:
slug wares categories
0 alex.payne macbook-pro developer
0 alex.payne macbook-pro mac
0 alex.payne macbook-pro web
0 alex.payne cinema-display developer
0 alex.payne cinema-display mac
0 alex.payne cinema-display web
0 alex.payne readynas-nv-plus developer
0 alex.payne readynas-nv-plus mac
0 alex.payne readynas-nv-plus web
1 jona.bechtolt audio-kontrol-1 mac
1 jona.bechtolt audio-kontrol-1 musician
1 jona.bechtolt powershot-sd1000 mac
1 jona.bechtolt powershot-sd1000 musician
1 jona.bechtolt live mac
1 jona.bechtolt live musician
In [14]: df1.denormalise('wares', 'categories').reset_index(drop=True)
Out[14]:
slug wares categories
0 alex.payne macbook-pro developer
1 alex.payne macbook-pro mac
2 alex.payne macbook-pro web
3 alex.payne cinema-display developer
4 alex.payne cinema-display mac
5 alex.payne cinema-display web
6 alex.payne readynas-nv-plus developer
7 alex.payne readynas-nv-plus mac
8 alex.payne readynas-nv-plus web
9 jona.bechtolt audio-kontrol-1 mac
10 jona.bechtolt audio-kontrol-1 musician
11 jona.bechtolt powershot-sd1000 mac
12 jona.bechtolt powershot-sd1000 musician
13 jona.bechtolt live mac
14 jona.bechtolt live musician