【问题标题】:numpy array add valuenumpy数组添加值
【发布时间】:2021-06-17 22:04:01
【问题描述】:

我正在尝试使用以下示例将新值添加到 numpy 数组中

dict_created = {"A": [0,0], "B": [0,0], "C": [0,0], "D": [0,0], 
                "E": [0,0], "F": [0,0], "G": [0,0]} 

res_array = np.array(list(dict_created.items())) 

现在,我想将"Q": [1,2] 添加到每个项目中,期望结果如下:

{"AQ": [1,2], "BQ": [1,2], "CQ": [1,2], "DQ": [1,2], "EQ": [1,2], "FQ": [1,2], "GQ": [1,2]}

我已尝试使用 + 号,但每个项目的值返回为 [0, 0, 1, 2],而不是与给定值相加。

返回预期结果的正确方法是什么?

谢谢你

【问题讨论】:

  • 您的 numpy.array 对象是一个奇怪的 dtype=object 数组。为什么不直接使用list? IOW,你为什么要使用 numpy?
  • 我不太明白您为什么希望 Numpy 在这里提供帮助。从根本上说,您正在尝试创建然后修改字典。 Numpy 不处理这些。您可以使用 Numpy 来表示然后更新该 dict 中的 (当前是列表,并且可能是 Numpy 数组),但是对于这么短的列表来说显然是矫枉过正。
  • 打印res_array 这样您和我们都清楚它是什么。

标签: python numpy


【解决方案1】:

你可以试试这个方法:

new_item = {"Q":[1,2]}
new_item = np.array(list(new_item.items()))
res_array = np.concatenate((res_array, new_item))

【讨论】:

  • @user4603876 很抱歉,我在从我的草图代码中更改名称时犯了一个错误。立即尝试。
【解决方案2】:

如果我理解正确,您想同时更新字典的键和值,这就是我的想法(使用 numpy 添加列表而不是附加列表):

import numpy as np

new_key = "Q"
new_value = [1,2]

result = dict((k+new_key, np.add(v, new_value)) for k, v in dict_created.items())

预期输出:

{'AQ': array([1, 2]), 'BQ': array([1, 2]), 'CQ': array([1, 2]), 'DQ': array([1, 2]), 'EQ': array([1, 2]), 'FQ': array([1, 2]), 'GQ': array([1, 2])}

您还可以执行以下操作(使用dictionary comprehension 的替代方式):

result = {k+new_key:np.add(v, new_value) for k, v in dict_created.items()}

编辑:

根据您的评论,键和值的组合将达到数十亿。即使使用 numpy,您也不应该期望一个快速的解决方案,但无论如何,Python dicts 都经过了很好的优化。

您可以通过以下问题查看更多关于性能的信息:

Python dictionary vs list, which is faster?

Python lists/dictionaries vs. numpy arrays: performance vs. memory control

Why is this loop faster than a dictionary comprehension for creating a dictionary?

对于过滤和排序示例,我已将 dict_created 修改为:

dict_created = {"A": [1,0], "B": [0,0], "C": [0,0], "D": [0,0], "E": [0,0], "F": [0,0], "G": [3,0]}
# Result
{'AQ': array([2, 2]), 'BQ': array([1, 2]), 'CQ': array([1, 2]), 'DQ': array([1, 2]), 'EQ': array([1, 2]), 'FQ': array([1, 2]), 'GQ': array([4, 2])}

过滤

# Filter elements with x > 1
filtered_dict = {k:v for k, v in result.items() if v[0] > 1}
# {'AQ': array([2, 2]), 'GQ': array([4, 2])}

排序

# Sorts keys
sorted_keys = sorted(result)
# ['AQ', 'BQ', 'CQ', 'DQ', 'EQ', 'FQ', 'GQ']
# Sorting by dict keys
sorted_with_kv = {k:v for k, v in sorted(result.items())}
# {'AQ': array([2, 2]), 'BQ': array([1, 2]), 'CQ': array([1, 2]), 'DQ': array([1, 2]), 'EQ': array([1, 2]), 'FQ': array([1, 2]), 'GQ': array([4, 2])}
# Sorting by x given [x, y]
sorted_with_kv_lambda = {k:v for k, v in sorted(result.items(), key=lambda elem: elem[1][0])}
# {'BQ': array([1, 2]), 'CQ': array([1, 2]), 'DQ': array([1, 2]), 'EQ': array([1, 2]), 'FQ': array([1, 2]), 'AQ': array([2, 2]), 'GQ': array([4, 2])}

您应该尝试坚持使用字典理解,因为它在使用 Python 字典时会产生最佳性能。

如需更深入的解释,我推荐阅读:How Do Dictionaries and Sets Work

【讨论】:

  • 谢谢。它有效,只是扩大了问题的范围。出于性能考虑。 dict_created 的大小将超过 100K,new_key_value 对的选择也将是另一个 10Kish ......我希望得到所有这些组合的乘积,然后进行一些过滤和排序。在这种情况下,最好的方法是什么?
  • @user4603876 更新了答案,希望对你有帮助:)
【解决方案3】:
In [88]: dict_created = {"A": [0,0], "B": [0,0], "C": [0,0], "D": [0,0],
    ...:                 "E": [0,0], "F": [0,0], "G": [0,0]}
    ...: 
    ...: res_array = np.array(list(dict_created.items()))
<ipython-input-88-bc8f2c25c347>:4: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray.

In [89]: res_array
Out[89]: 
array([['A', list([0, 0])],
       ['B', list([0, 0])],
       ['C', list([0, 0])],
       ['D', list([0, 0])],
       ['E', list([0, 0])],
       ['F', list([0, 0])],
       ['G', list([0, 0])]], dtype=object)

您已经创建了一个包含字母和列表的对象 dtype 数组。

您不清楚添加内容,但假设您做了:

In [91]: res_array+list({"Q": [1,2]}.items())
<ipython-input-91-1bdaa5aac0d7>:1: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray.

Out[91]: 
array([['AQ', list([0, 0, 1, 2])],
       ['BQ', list([0, 0, 1, 2])],
       ['CQ', list([0, 0, 1, 2])],
       ['DQ', list([0, 0, 1, 2])],
       ['EQ', list([0, 0, 1, 2])],
       ['FQ', list([0, 0, 1, 2])],
       ['GQ', list([0, 0, 1, 2])]], dtype=object)

第一列是字符串,+是字符串拼接。

第二个是列表,有类似的连接。

您想要为第二列添加数组。

让我们把那一列变成数组:

In [93]: res_array[:,1]=[np.array(i) for i in res_array[:,1]]
In [94]: 
In [94]: res_array
Out[94]: 
array([['A', array([0, 0])],
       ['B', array([0, 0])],
       ['C', array([0, 0])],
       ['D', array([0, 0])],
       ['E', array([0, 0])],
       ['F', array([0, 0])],
       ['G', array([0, 0])]], dtype=object)
In [95]: 
In [95]: res_array+list({"Q": np.array([1,2])}.items())
<ipython-input-95-2703d0356b14>:1: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray.

Out[95]: 
array([['AQ', array([1, 2])],
       ['BQ', array([1, 2])],
       ['CQ', array([1, 2])],
       ['DQ', array([1, 2])],
       ['EQ', array([1, 2])],
       ['FQ', array([1, 2])],
       ['GQ', array([1, 2])]], dtype=object)

我将留下 np 1.19 版开始添加的“参差不齐的数组”警告。您应该知道您正在创建一个非标准的numpy 数组,并对其进行适当的处​​理。从 dict 创建一个 numpy 数组,特别是如果你想要键和值都有点奇怪。 numpy 最适合具有统一 dtype 的数组 - 所有字符或所有数字。这种混杂的东西很尴尬。

这是一种制作新字典的非 numpy 方式:

In [97]: newdict= {key+'Q': [i+j for i,j in zip(value,[1,2])] for key, value in dict_created.items()}

In [98]: newdict
Out[98]: 
{'AQ': [1, 2],
 'BQ': [1, 2],
 'CQ': [1, 2],
 'DQ': [1, 2],
 'EQ': [1, 2],
 'FQ': [1, 2],
 'GQ': [1, 2]}

【讨论】:

    猜你喜欢
    • 2022-01-24
    • 1970-01-01
    • 2021-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-02
    • 1970-01-01
    相关资源
    最近更新 更多