熊猫:通过列表列表的映射来创建列

时间:2020-10-12 15:39:36

标签: python pandas dictionary mapping

我有一个熊猫数据框和一个字典,如下所示。我想在数据框中创建一个新列,基于该行的索引从字典中出现的列表中。

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”中可能有约数百个键,每个列表将包含数万个项目。另外,我将主要处理整数而不是字符串,如下所示。

2 个答案:

答案 0 :(得分:4)

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

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 :(得分:1)

这将循环遍历索引值,并在字典的值中查找它们。即使它看起来不那么漂亮,它的运行速度也比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的解决方案将变得更快。 Alollz创建value:key dict会产生大量开销,因此对于少量数据,这会更快。