python-2.7 - 如何处理在每个单元格中都有一个字典列表的 Pandas 列

标签 python-2.7 pandas pytables hdfstore

我有一个 DataFrame,其中包含一个列,其中每个单元格都由一个 dicts 列表组成,并且每个 dicts 列表的长度不同(包括 0)。

一个例子:

df = pd.DataFrame({'ID' : [13423,294847,322844,429847], 'RANKS': [[{u'name': u'A', u'price': u'$1.00', u'rank': u'1'},
{u'name': u'B', u'price': u'$4.00', u'rank': u'2'},
{u'name': u'C', u'price': u'$3.99', u'rank': u'3'},
{u'name': u'D', u'price': u'$2.00', u'rank': u'4'},
{u'name': u'E', u'price': u'$2.50', u'rank': u'5'}],

[{u'name': u'AA', u'price': u'$1.99', u'rank': u'1'},
{u'name': u'BB', u'price': u'$6.99', u'rank': u'2'}],

[{u'name': u'Z', u'price': u'$0.99', u'rank': u'1'},
{u'name': u'Y', u'price': u'$10.00', u'rank': u'2'},
{u'name': u'X', u'price': u'$1.99', u'rank': u'3'}],[]], 'count' : [5,2,3,0]})

请注意,“count”是“RANKS”中的字典数。我的目标是创建一系列额外的数据帧/表(每个“等级”一个)并将它们链接到 HDFStore 中的主表。就像是:
Rank_2
ID       Price   Name
13423    $4.00    B  
294847   $6.99    BB 
322844   $10.99   Y 
429847   NaN      NaN   


Rank_3
ID       Price   Name
13423    $3.99    C  
294847   NaN      NaN 
322844   $1.99    X 
429847   NaN      NaN   

通过这种方式,我可以在需要时轻松查询 ID 和排名,但主表不会因分层数据的展开而变得困惑。

但是,问题是我无法弄清楚如何从此列创建 DataFrame。我已经尝试了很多事情,第一个(如果有效,则嵌套在 for 循环中,但当然没有):
Rank_1 = pd.DataFrame(df.loc[df['count'] > 0]['RANKS'].map(lambda x: pd.DataFrame(x[0])))

其次,因为价格对我来说是最重要的部分:
for i in range(0,5):
    df['rank_%s' % str(i+1)] = df[df['count'] > i]['RANKS'].map(lambda x: x[i]['price'].strip('$'))

然后转换为 float 。这行得通,但这是一个相当大的妥协。有没有一种有效的方法(不会卡在 NaN 上)来实现我为每个等级设置单独 DataFrame 的目标?

最佳答案

我的直觉 react 是你可能不应该把你的 DataFrame 分解成
许多较小的数据帧。处理大量小型 DataFrame 需要 Python
循环,这通常是通往缓慢之路的一步。相反我认为你
使用一个 DataFrame 可能会更好,这会使 dicts 列表变平,因此
每个内部字典在 DataFrame 中都有自己的行。的 key
内部 dict 将成为新列。我怀疑这种单一的平面 DataFrame 格式
将能够做多个 DataFrame 替代品可以做的任何事情,但是
更快,并且可以使保存到 HDFStore 变得简单。

假设您有一个 DataFrame,其中包含 RANKS 中的字典列表。柱子:

import numpy as np
import pandas as pd

df = pd.DataFrame({'ID' : [13423,294847,322844,429847], 'RANKS': [[{u'name': u'A', u'price': u'$1.00', u'rank': u'1'},
{u'name': u'B', u'price': u'$4.00', u'rank': u'2'},
{u'name': u'C', u'price': u'$3.99', u'rank': u'3'},
{u'name': u'D', u'price': u'$2.00', u'rank': u'4'},
{u'name': u'E', u'price': u'$2.50', u'rank': u'5'}],

[{u'name': u'AA', u'price': u'$1.99', u'rank': u'1'},
{u'name': u'BB', u'price': u'$6.99', u'rank': u'2'}],

[{u'name': u'Z', u'price': u'$0.99', u'rank': u'1'},
{u'name': u'Y', u'price': u'$10.00', u'rank': u'2'},
{u'name': u'X', u'price': u'$1.99', u'rank': u'3'}],[]], 'count' : [5,2,3,0]})

然后你可以像这样构建一个每行一个字典的平面 DataFrame:
result = []
for idx, row in df.iterrows():
    for dct in row['RANKS']:
        dct['ID'] = row['ID']
        dct['count'] = row['count']
        result.append(dct)
del df
result = pd.DataFrame(result)
result['rank'] = result['rank'].astype(np.int32)
result['price'] = result['price'].str.replace('$', '')
result['price'] = result['price'].astype('float')
print(result)

这产生
       ID  count name  price  rank
0   13423      5    A   1.00     1
1   13423      5    B   4.00     2
2   13423      5    C   3.99     3
3   13423      5    D   2.00     4
4   13423      5    E   2.50     5
5  294847      2   AA   1.99     1
6  294847      2   BB   6.99     2
7  322844      3    Z   0.99     1
8  322844      3    Y  10.00     2
9  322844      3    X   1.99     3

注意建筑result直接来自原始数据源(从而完全避免 df)将是一个更干净、对内存要求更低的解决方案。

关于python-2.7 - 如何处理在每个单元格中都有一个字典列表的 Pandas 列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28655405/

相关文章:

python - 用 python 生成/合成声音?

python - 在列表python中拆分Mac地址

python - 如何在hdf5表中存储空值?

python - 获取 Pytables 一维数组中值的索引

Python Tkinter : multiple images and text on a BIG button?

python - 在 3D 轴上绘制 2D 轮廓集

python - 对日期序列进行排序的最 pythonic 方法是什么?

python - 在 pandas 中拆垛时保持顺序

python - 基于列组合的向量乘法多个数据帧

pytables - 如何加快列表中数据的检索速度