如何将字典中的值附加到列表?

How to append value from a dictionary to list?

我有字典d

d = {'word': [0,1,2,3,4,5,6], 'data':[2,3,4,5,6,7,8], 'mark': [1,4,5,2,5,6,7]}

和一个包含列表的数据框

df = (pd.DataFrame({data:[
              ['data', 'customer', 'mark', 'hello', 'spam', 'life'], 
              ['from','the', 'word', 'mark', 'data'], 
              ['hello', 'word', 'mark', 'data', 'the']]}, 
              index = [0,1,2]))

上面的df代码中,单词分为6列,每列一个单词,但在我的实际示例中,它们都在一列中,并且是一个大列表。

我想将数据框每个列表中的单词与字典中的键匹配。如果出现该词,则将字典中的相应值附加到数据框中的词,如果不出现,则从列表中省略该词。

输出应如下所示:

new_df = [[[data,2,3,4,5,6,7,8], [mark,1,4,5,2,5,6,7]], 
          [[word,0,1,2,3,4,5,6], [mark,1,4,5,2,5,6,7], [data, 2,3,4,5,6,7,8]], 
          [[word,0,1,2,3,4,5,6], [mark,1,4,5,2,5,6,7], [data, 2,3,4,5,6,7,8]]]

因为在第一个列表中,我们在原始词典中没有customerhellospamlife这些词。同样,在下一个列表中,我们没有单词 fromthe 等等...

实现此目标的最佳方法是什么?

我做了这样的事情:

def checkkey(dict, key):
if key in dict.keys():
    key.append(dict[key])
else:
    print("Not present")


checkkey(d,a)

其中 d 是这本字典,a ='data'

如何对列表和整个数据框中的所有单词执行此操作?

像这样创建数据框:

df = (pd.DataFrame({'data': [
                 ['data', 'customer', 'mark', 'hello', 'spam', 'life'], 
                 ['from','the', 'word', 'mark', 'data'], 
                 ['hello', 'word', 'mark', 'data', 'the']]}, 
                 index = [0,1,2]))

>>> df
                                       data
0  [data, customer, mark, hello, spam, life]
1              [from, the, word, mark, data]
2             [hello, word, mark, data, the]

使用:

方法一:

df =  (df['data'].apply(lambda x: 
                [[name] + d[name] for name in x if name in d]))
>>> df
0    [[data, 2, 3, 4, 5, 6, 7, 8], [mark, 1, 4, 5, ...
1    [[word, 0, 1, 2, 3, 4, 5, 6], [mark, 1, 4, 5, ...
2    [[word, 0, 1, 2, 3, 4, 5, 6], [mark, 1, 4, 5, ...

方法 2: 如果您在每个列表中都有唯一值,那么您可以使用:

df = (df['data'].apply(lambda x: [[name] + d[name] 
                    for name in set(x).intersection(d)]))

这可能会快一点。


方法三: .apply 通常很慢,所以我在不使用应用的情况下发布了另一种方法。虽然看起来这里有更多的操作,但很可能这比 .apply.

首先让我们更改字典以在值列表中包含键。

d = {k: [k] + v  for k, v in d.items()}
>>> d
{'word': ['word', 0, 1, 2, 3, 4, 5, 6], 'data': ['data', 2, 3, ...

不是先分解数据框以将列表的每个值放在新行中。

df1 = df.explode(column = 'data')

>>> df1
           data
    0      data
    0  customer
    0      mark
    0     hello
    0      spam
    0      life
    1      from
    1       the
    ...

现在做映射,然后使用索引合并行。

 df1.data = df1.data.map(d)
 df1 = df1.dropna()
 df1 = df1.groupby(df1.index).agg(lambda x: x.tolist())

>>> df1
                                                data
0  [[data, 2, 3, 4, 5, 6, 7, 8], [mark, 1, 4, 5, ...
1  [[word, 0, 1, 2, 3, 4, 5, 6], [mark, 1, 4, 5, ...
2  [[word, 0, 1, 2, 3, 4, 5, 6], [mark, 1, 4, 5, ...

我已经重新格式化了您在问题中指定的数据框。我想这就是您要找的东西 :

d = {'word': [0,1,2,3,4,5,6], 'data':[2,3,4,5,6,7,8], 'mark': [1,4,5,2,5,6,7]}
df = pd.DataFrame({"data":[['data', 'customer', 'mark', 'hello', 'spam', 'life'],['from','the', 'word', 'mark', 'data'],
                   ['hello', 'word', 'mark', 'data', 'the']]})

解决方案:

def check_word(x,d):
    return [[i,d[i]] for i in x if i in d]
            
df['data'] = df['data'].apply(lambda x:check_word(x,d))

print(df.data.values)

# ---- Output -----
# array([list([['data', [2, 3, 4, 5, 6, 7, 8]], ['mark', [1, 4, 5, 2, 5, 6, 7]]]),
#   list([['word', [0, 1, 2, 3, 4, 5, 6]], ['mark', [1, 4, 5, 2, 5, 6, 7]], ['data', [2, 3, 4, 5, 6, 7, 8]]]),
#   list([['word', [0, 1, 2, 3, 4, 5, 6]], ['mark', [1, 4, 5, 2, 5, 6, 7]], ['data', [2, 3, 4, 5, 6, 7, 8]]])],
#  dtype=object)