如何将字典中的值附加到列表?
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]]]
因为在第一个列表中,我们在原始词典中没有customer
、hello
、spam
、life
这些词。同样,在下一个列表中,我们没有单词 from
、the
等等...
实现此目标的最佳方法是什么?
我做了这样的事情:
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)
我有字典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]]]
因为在第一个列表中,我们在原始词典中没有customer
、hello
、spam
、life
这些词。同样,在下一个列表中,我们没有单词 from
、the
等等...
实现此目标的最佳方法是什么?
我做了这样的事情:
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)