使用字典列向熊猫数据帧添加行



>我有一个这样的数据帧:

matrix = [(222, {'a': 1, 'b':3, 'c':2, 'd':1}),
         (333, {'a': 1, 'b':0, 'c':0, 'd':1})]
df = pd.DataFrame(matrix, columns=['ordernum', 'dict_of item_counts'])
   ordernum               dict_of item_counts
0       222  {'a': 1, 'b': 3, 'c': 2, 'd': 1}
1       333  {'a': 1, 'b': 0, 'c': 0, 'd': 1}

我想创建一个数据帧,其中每个ordernum对每个字典键重复dict_of_item_counts不是 0。我还想创建一个显示此行的相应字典键的key列以及一个包含字典值的value列。最后,我还会ordernum_index,用于计算每个ordernum的数据帧中的不同行。

最终数据帧应如下所示:

ordernum      ordernum_index      key     value
222           1                   a       1
222           2                   b       3 
222           3                   c       2
222           4                   d       1
333           1                   a       1
333           2                   d       1 

任何帮助将不胜感激:)

始终尝试构建数据,可以轻松完成,如下所示:

>>> matrix
[(222, {'a': 1, 'b': 3, 'c': 2, 'd': 1}), (333, {'a': 1, 'b': 0, 'c': 0, 'd': 1})]
>>> data = [[item[0]]+[i+1]+list(value) for item in matrix for i,value in enumerate(item[1].items()) if value[-1]!=0]
>>> data
[[222, 1, 'a', 1], [222, 2, 'b', 3], [222, 3, 'c', 2], [222, 4, 'd', 1], [333, 1, 'a', 1], [333, 4, 'd', 1]]
>>> pd.DataFrame(data, columns=['ordernum', 'ordernum_index', 'key', 'value'])
   ordernum  ordernum_index key  value
0       222               1   a      1
1       222               2   b      3
2       222               3   c      2
3       222               4   d      1
4       333               1   a      1
5       333               4   d      1

通过将applypd.Series一起使用来扩展字典,并使用concat将其连接到其他列(ordernum(。请参阅下面的中间结果 df2 。现在要将每一列变成一行,请使用 melt ,然后使用 query 删除所有 0 行,最后assign cumcount以获取索引(排序后(并添加 1 从 1 开始计数,而不是 0。

df2 = pd.concat([df[['ordernum']], df['dict_of item_counts'].apply(pd.Series)], axis=1)
(df2.melt(id_vars='ordernum', var_name='key')
.query('value != 0')
.sort_values(['ordernum', 'key'])
.assign(ordernum_index = lambda df: df.groupby('ordernum').cumcount().add(1)))
#   ordernum key  value  ordernum_index
#0       222   a      1               1
#2       222   b      3               2
#4       222   c      2               3
#6       222   d      1               4
#1       333   a      1               1
#7       333   d      1               2

现在 df2 看起来像:

#   ordernum  a  b  c  d
#0       222  1  3  2  1
#1       333  1  0  0  1
您可以通过

解压缩字典来做到这一点,同时使用 iterrows 访问字典并从ordernum, key, value中创建元组。

最后,为了创建您的ordernum_index我们在ordernum上分组并执行cumcount

data = [(r['ordernum'], k, v) for _, r in df.iterrows() for k, v in r['dict_of item_counts'].items() ]
new = pd.DataFrame(data, columns=['ordernum', 'key', 'value']).sort_values('ordernum').reset_index(drop=True)
new['ordernum_index'] = new[new['value'].ne(0)].groupby('ordernum').cumcount().add(1)
new.dropna(inplace=True)

   ordernum key  value  ordernum_index
0       222   a      1             1.0
1       222   b      3             2.0
2       222   c      2             3.0
3       222   d      1             4.0
4       333   a      1             1.0
7       333   d      1             2.0

构造数据帧df1,使用 df['dict_of item_counts'].tolist() 表示值,使用 df.ordernum 表示索引。 replace 0 表示 np.nanstack 表示 dropna=True 可忽略 0 值。 reset_index获取所有列。

接下来,使用 groupbycumcount 创建列ordernum_index

最后,将列名称更改为适当的名称。

df1 = pd.DataFrame(df['dict_of item_counts'].tolist(), index=df.ordernum).replace(0, np.nan).stack(dropna=True).reset_index(name='value')
df1['ordernum_index'] = df1.groupby('ordernum')['value'].cumcount() + 1
df1 = df1.rename(columns={'level_1': 'key'})
Out[732]:
   ordernum key  value  ordernum_index
0       222   a    1.0               1
1       222   b    3.0               2
2       222   c    2.0               3
3       222   d    1.0               4
4       333   a    1.0               1
5       333   d    1.0               2

最新更新