Pandas:通过从列表的字典映射创建一列

Posted

技术标签:

【中文标题】Pandas:通过从列表的字典映射创建一列【英文标题】:Pandas: create a column by mapping from a dict of lists 【发布时间】:2021-01-26 22:48:24 【问题描述】:

我有一个 pandas 数据框和一个字典,如下所示。我想根据行索引出现在字典中的哪个列表在数据框中创建一个新列。

df = pd.DataFrame(
    'a':['x', 'y', 'z'],
    'b':[1, 2, 3],
    'c':[10, 20, 30],
)
df = df.set_index('a')
mydict = 
    'g1':['a', 'b', 'y'],
    'g2':['x', 'k', 'l'],
    'g3':['m', 'l', 'z'],

预期输出

   b   c   g
a       
x  1  10  g2
y  2  20  g1
z  3  30  g3

我什至不知道如何开始解决这个问题。可以使用它创建一个自定义函数和映射吗?但这是否足够高效?在我的实际用例中,“df”中可能有数十万行,“mydict”中可能有大约数百个键,每个列表将包含数万个项目。此外,我将主要处理整数而不是字符串,如此处所示。

【问题讨论】:

'l' 出现在该字典中不同键的列表中,那么在这种情况下会发生什么? 这通常不会发生,但如果发生这种情况,“g2”或“g3”都可以。 【参考方案1】:

您需要将列表字典扁平化为带有标量键:值对的简单字典。由于字典需要唯一的键,如果多个列表包含相同的值,则该值最终会映射到它所属的最后一个列表的键(这很好,因为您不在乎哪个)。

d = val:key for key, lst in mydict.items() for val in lst
#'a': 'g1', 'b': 'g1', 'y': 'g1',
# 'x': 'g2', 'k': 'g2', 
# 'l': 'g3', 'm': 'g3', 'z': 'g3'

df['g'] = df.index.map(d)
#   b   c   g
#a           
#x  1  10  g2
#y  2  20  g1
#z  3  30  g3

【讨论】:

这看起来是个不错的解决方案。我将在我更大的数据集上对其进行测试并接受它作为答案。同时+1,非常感谢!!【参考方案2】:

这循环遍历索引值并在字典的值中查找它们。它的运行速度比 Alollz 解决方案快约 7-10 倍**,尽管它看起来并不那么漂亮。

g = []
for i in df.index.values:
    for k in mydict:
        if i in mydict[k]:
            g.append(k)
            break
df['g'] = g

** 对于像问题中的示例这样的小数据,速度更快。随着数据量的增加,Alollz 的解决方案将变得更快。 Allollz 的 value:key dict 的创建有很多开销,所以对于少量数据来说这更快。

【讨论】:

谢谢。但是嵌套循环让我害怕 :) 我会测试一下! 随着 DataFrame 变大,这个方法会变得很慢,但是对于小 ~ 千行数据帧来说非常快

以上是关于Pandas:通过从列表的字典映射创建一列的主要内容,如果未能解决你的问题,请参考以下文章

通过从多个列中删除匹配的电子邮件域来过滤 Pandas 数据框

Pandas:当字典中有多个键时,通过映射添加列

将 pandas Dataframe 列映射到字典值

Python Pandas 创建一长串要连接的数据框

Pandas:根据另一列的键在现有列上映射字典值以替换 NaN

通过字典列表过滤 pandas DataFrame