使用 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 对数据进行非规范化的主要内容,如果未能解决你的问题,请参考以下文章

使用 Pig 对大型数据框进行非规范化

Symfony 2 使用自定义非规范化器对嵌套对象进行非规范化

如何在 javascript 中最有效地对规范化数据进行非规范化

神经网络中预测数据的非规范化

如何使用 pandas groupby() 的 split-apply-combine 模式同时规范化多个列

如何通过 Python Pandas 正确规范化 json