使用 Pandas 对数据进行非规范化
Posted
技术标签:
【中文标题】使用 Pandas 对数据进行非规范化【英文标题】:Denormalise the data using Pandas 【发布时间】:2013-06-30 04:42:23 【问题描述】:如果我有以下格式的数据(存储在 pandas 数据框中),本质上是分类和商品的标准化形式:
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 我最终没有按照我最初打算的方式进行非规范化,而是仅循环遍历感兴趣的列。但是任何更好地去规范化的能力都会使它变得更好。
【问题讨论】:
你能显示你当前的代码吗? 相关:***.com/questions/17116814/… 【参考方案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
【讨论】:
以上是关于使用 Pandas 对数据进行非规范化的主要内容,如果未能解决你的问题,请参考以下文章
Symfony 2 使用自定义非规范化器对嵌套对象进行非规范化
如何在 javascript 中最有效地对规范化数据进行非规范化