Python np.append 不适用于 numpy.ndarray 类型的字典值
Posted
技术标签:
【中文标题】Python np.append 不适用于 numpy.ndarray 类型的字典值【英文标题】:Python np.append does not work on dictionary value which is of type numpy.ndarray 【发布时间】:2020-07-23 09:04:14 【问题描述】:我有一个函数,它给定两个 numpy 数组,将它们转换为字典,如下所示
def seggregate_based_on_y(X,y):
dictionary=
for index in range(len(y)):
if y[index] in dictionary.keys():
np.append(dictionary[y[index]],X[index])
else:
dictionary[y[index]]=np.array([X[index]])
return dictionary
用于以下输入
X=np.array([[1,1],[2,2],[3,3],[4,4],[5,5]])
y=np.array([2,3,2,3,4])
d=seggregate_based_on_y(X,y)
print(d)
我希望 'd' 为 2: array([[1, 1],[3,3]]), 3: array([[2, 2],[4,4]]), 4: array([[5, 5]])
,但我得到的 'd' 为 2: array([[1, 1]]), 3: array([[2, 2]]), 4: array([[5, 5]])
,即 if 语句不起作用。应该怎么做?
【问题讨论】:
见docs.scipy.org/doc/numpy/reference/generated/numpy.append.htmlappend()
返回一个它不工作的数组的副本。
@MarkMeyer 感谢您指出,我不知道。但是问题仍然存在,您知道是否有任何方法可以按预期获得上述结果
【参考方案1】:
首先,就像 cmets 所说,您必须为字典分配新值。请参阅以下修复:
def seggregate_based_on_y(X,y):
dictionary=
for index in range(len(y)):
if y[index] in dictionary.keys():
dictionary[y[index]] = np.append(dictionary[y[index]],X[index])
else:
dictionary[y[index]]=np.array([X[index]])
return dictionary
使用给定的数据输出:
2: array([1, 1, 3, 3]), 3: array([2, 2, 4, 4]), 4: array([[5, 5]])
这与您的预期结果不同,因为np.append
将附加到同一个向量。要获得所需的输出,请使用np.vstack
def seggregate_based_on_y(X,y):
dictionary=
for index in range(len(y)):
if y[index] in dictionary.keys():
dictionary[y[index]] = np.vstack((dictionary[y[index]],X[index]))
else:
dictionary[y[index]]=np.array([X[index]])
return dictionary
这里的输出是:
2: array([[1, 1],
[3, 3]]), 3: array([[2, 2],
[4, 4]]), 4: array([[5, 5]])
我希望这会有所帮助。
【讨论】:
【参考方案2】:你可以使用内置函数zip
:
def seggregate_based_on_y(X,y):
d =
for k, v in zip(y, X):
if k in d:
d[k] = np.append(d[k], v.reshape(1, 2), axis=0)
else:
d[k] = v.reshape(1, 2)
return d
X=np.array([[1,1],[2,2],[3,3],[4,4],[5,5]])
y=np.array([2,3,2,3,4])
print(seggregate_based_on_y(X,y))
输出:
2: array([[1, 1],
[3, 3]]), 3: array([[2, 2],
[4, 4]]), 4: array([[5, 5]])
【讨论】:
【参考方案3】:试试这个
import numpy as np
def seggregate_based_on_y(X,y):
dictionary=
for index in range(len(y)):
if y[index] in dictionary.keys():
z = np.append(dictionary[y[index]], X[index])
dictionary[y[index]] = z.reshape(z.size // 2, 2)
else:
dictionary[y[index]]=np.array([X[index]])
return dictionary
X=np.array([[1,1],[2,2],[3,3],[4,4],[5,5]])
y=np.array([2,3,2,3,4])
d=seggregate_based_on_y(X,y)
print(d)
输出:
2: array([[1, 1],[3, 3]]), 3: array([[2, 2],[4, 4]]), 4: array([[5, 5]])
【讨论】:
【参考方案4】:defaultdict
可以轻松完成此类收集:
In [268]: from collections import defaultdict
In [269]: x = [[1,1],[2,2],[3,3],[4,4],[5,5]]
In [270]: y = [2,3,2,3,4]
In [271]: dd = defaultdict(list)
In [272]: for i,j in zip(y, x):
...: dd[i].append(j)
...:
In [273]: dd
Out[273]: defaultdict(list, 2: [[1, 1], [3, 3]], 3: [[2, 2], [4, 4]], 4: [[5, 5]])
如果结果必须是数组而不是列表,则可以转换为:
In [274]: d = k: np.array(dd[k]) for k in dd
In [275]: d
Out[275]:
2: array([[1, 1],
[3, 3]]), 3: array([[2, 2],
[4, 4]]), 4: array([[5, 5]])
列表追加比np.append
(或任何numpy
concatenate
系列函数)快。列表追加就地操作。
defaultdict
可以直接构建一个数组(但我希望这会更慢):
In [280]: dd = defaultdict(lambda:np.zeros((0,2),int))
In [281]: for i,j in zip(y, x):
...: dd[i] = np.vstack((dd[i],j))
...:
In [282]: dd
Out[282]:
defaultdict(<function __main__.<lambda>()>, 2: array([[1, 1],
[3, 3]]), 3: array([[2, 2],
[4, 4]]), 4: array([[5, 5]]))
【讨论】:
以上是关于Python np.append 不适用于 numpy.ndarray 类型的字典值的主要内容,如果未能解决你的问题,请参考以下文章
Python基础:Numpy函数介绍:Meshgrid,mgrid,append等
Python基础:Numpy函数介绍:Meshgrid,mgrid,append等