对于包含一列键和一列值的数据帧,创建另一列字典

2024-04-27 00:23:45 发布

您现在位置:Python中文网/ 问答频道 /正文

我有以下数据帧:

    c1  c2          freq
0   a   [u]         [4]
1   b   [x, z, v]   [8, 3, 15]

我想换一个专栏“dict”这样

    c1  c2          freq         dict
0   a   [u]         [4]          {'u':4}
1   b   [x, z, v]   [8, 3, 15]   {'x':8, 'z':3, 'v':15}

我正在尝试以下代码:d["dict"] = d.apply(lambda row: dict(zip(row["c2"], row["freq"])))但这会产生错误: KeyError: ('c2', u'occurred at index c1')

不知道我做错了什么。整个练习是这样定义一个全局字典:{"u":4, "v":15, "x":8, "z":3},我的初始数据帧是:

    c1  c2
0   a   u
1   b   [x, z, v]

其中[x, z, v]是一个numpy数组。对于每一行,我希望保留全局字典中具有最高值的前2个元素(如果是数组),因此对于第二行,我将保留xv。为此,我将c2列的每个元素转换为一个列表,创建了一个具有各自频率的新列,现在想转换为一个字典,以便可以按值对其进行排序。那我就保留那一行字典的前两个键

d["c2"] = d["c2"].apply(lambda x: list(set(x)))
d["freq"] = d["c2"].apply(lambda x: [c[j] for j in x])
d["dict"] = d.apply(lambda row: dict(zip(row["c2"], row["freq"])))

第三条线引起了一个问题。另外,如果有一个更有效的程序来做整个事情,我很乐意得到任何建议。谢谢


Tags: 数据lambda代码元素字典数组zip全局
2条回答

通过使用内置的sortedkeyreverse参数,您可以更轻松地解决核心问题。您只需准备一个partial func并将其映射到列上,以及方法链接样式中的首选子集func:

import pandas as pd
from functools import partial

df = pd.DataFrame({'c1': ['a', 'b'], 'c2': ['u', ['x','z','v']]})

c = {"u":4, "v":15, "x":8, "z":3}

sorter = partial(sorted, key=lambda x: c[x], reverse=True)

def subset(l):
    return l[:2]

df['highest_two'] = df['c2'].map(sorter).map(subset)

print(df)

"""
Out:
      c1         c2 highest_two
    0  a          u         [u]
    1  b  [x, z, v]      [v, x]
"""

使用列表理解:

df['dict'] = [dict(zip(a,b)) for a, b in zip(df['c2'], df['freq'])]
print (df)
  c1         c2        freq                       dict
0  a        [u]         [4]                   {'u': 4}
1  b  [x, z, v]  [8, 3, 15]  {'x': 8, 'z': 3, 'v': 15}

或者在解决方案中为每行处理添加axis=1

df["dict"] = df.apply(lambda row: dict(zip(row["c2"], row["freq"])), axis=1)

相关问题 更多 >