将字典值与数据框内列表中的值进行匹配

时间:2014-09-09 22:45:27

标签: python python-2.7 pandas

我有一个包含列的数据框,相关的是ID和名称。我还有一个字典,对ID:name。我需要匹配ID并将名称输出到df ['name']列。我遇到的问题是,在数据框中,某些ID每行都有多个ID。如何单独迭代每个ID。

我的代码如下。如果只有一个ID,它可以工作。如果有多个ID,我无法弄清楚如何让它工作。我想它会被视为一个子列表?

for id_col, name_col in dic1.iteritems():
    df.loc[(df['ID Value'] == id_col), 'name'] = name_col

示例数据框:

df_test = pd.DataFrame( {'ID Value' : [130, (12,45,100), 208], 'name' : ['','','']})

df_test>>

   ID Value           name
0  130
1  (12, 45, 100)
2  208

DIC1:

 45 Joe 
130 Andy
208 Mary

我想要的结果是:

    ID Value       name
 0  130            Andy
 1  (12, 45, 100)  Joe
 2  208            Mary

2 个答案:

答案 0 :(得分:0)

我不确定将元组和数字混合为ID(将它们全部转换为元组是正确的解决方案是多么有用?)。
无论如何,你可以使用apply:

来做到这一点
In [11]: d = {45: "Joe", 130: "Andy", 208: "Mary"}

In [12]: f_test['ID Value'].apply(lambda x: d.get(x) or next(d.get(y) for y in x if d.get(y)))
Out[12]:
0    Andy
1     Joe
2    Mary
Name: ID Value, dtype: object

应用中的函数首先查看ID是否在字典中(并且元组赢了),如果是,则为此,如果它没有找到第一个那是......


这可能值得成为一个合适的功能:

def get_int_or_tuple(x, d=d):
    try:
        return d[x]
    except KeyError:  # hopefully that means it's iterable!
        for y in x:
            if y in d:
                return d[y]

In [21]: f_test['ID Value'].apply(get_int_or_tuple)
Out[21]:
0    Andy
1     Joe
2    Mary
Name: ID Value, dtype: object

答案 1 :(得分:0)

这将按预期输出结果,但请记住,对于元组中有多个ID的情况,您只需指定一个名称。

import pandas as pd

dic = {"Joe" : 45, "Andy" : 130, "Mary" : 208}

df = pd.DataFrame( {'ID Value' : [130, (12,45,100), 208], 'name' : ['','','']})

def getKey(match, dict):
    for key, value in dict.iteritems():
        if value == match:
            return key

for row in range(0, len(df)):
    ids = df['ID Value'][row]

    if isinstance(ids, int):
        name = getKey(ids, dic)
        if name != None:
            df['name'][row] = name
    elif isinstance(ids, tuple):
        for id in ids:
            name = getKey(id, dic)
            if name != None:
                df['name'][row] = name

print(df)
        ID Value  name
0            130  Andy
1  (12, 45, 100)   Joe
2            208  Mary

[3 rows x 2 columns]