用列表中的数字替换numpy数组中的数字

时间:2019-07-26 16:35:58

标签: python python-3.x numpy

我有一个2D的numpy数组,我希望将其内容替换为按索引列出的数字。

下面是一个代码段,用于更清楚地描述它:

import numpy as np
x = np.array([
              [2, 'something'],
              [2, 'more'],
              [6, 'and more'],
              [11, 'and so on'],
              [11, 'etc..']
             ])

y = [1, 2, 3]

我尝试通过以下代码来执行此操作,但出现错误,无法弄清楚为什么会发生这种情况。

k = x[:, 0]
z = [2, 6, 11]
j = 0
for i in range(z[0], z[-1] + 1):
    k = np.where(i in k, y[j])
    j+=1

运行以上代码时出错:

Traceback (most recent call last):

  File "<ipython-input-10-c48814c42718>", line 4, in <module>
    k = np.where(i in k, y[j])

ValueError: either both or neither of x and y should be given

我想要的输出数组:

# The output array which I intend to get
output = [
          [1, 'something'],
          [1, 'more'],
          [2, 'and more'],
          [3, 'and so on'],
          [3, 'etc..']
         ]

4 个答案:

答案 0 :(得分:4)

如果我理解正确,这是您可以做到的一种方法:

import numpy as np

x = np.array([
              [2, 'something'],
              [2, 'more'],
              [6, 'and more'],
              [11, 'and so on'],
              [11, 'etc..']
             ])
y = np.array([1, 2, 3])
# Find places where value changes, do cumsum and add a 0 at the beginning, then index y
x[:, 0] = y[np.r_[0, np.cumsum(np.diff(x[:, 0].astype(np.int32)) != 0)]]
# [['1' 'something']
#  ['1' 'more']
#  ['2' 'and more']
#  ['3' 'and so on']
#  ['3' 'etc..']]

请注意,这里的结果是字符串,因为这是输入数组的类型(除非指定了dtype=object,否则NumPy会强制转换为字符串)。无论如何,如果您要使用混合类型的数组,则应考虑使用structured array

答案 1 :(得分:3)

public void setTimeInfoDialogListener(TimeInfoDialogListener l){ this.timeListener = l; } + numpy.unique

您可以根据列中的不同元素创建映射,并使用基本的numpy索引将这些值映射到输入列表。


return_inverse=True

y = np.array([1, 2, 3])

_, inv = np.unique(x[:, 0], return_inverse=True)

x[:, 0] = y[inv]

这个答案的一个警告是,如果另一个array([['1', 'something'], ['1', 'more'], ['2', 'and more'], ['3', 'and so on'], ['3', 'etc..']], dtype='<U11') 出现在数组的后面,它将用2代替它,而不是新的值,但是您需要澄清问题这是个问题。

根据替换列表的大小,这似乎是所希望的行为。

答案 2 :(得分:0)

您可以通过获取唯一值,以蛮力方式对它们进行排序并使用for循环进行映射来实现此目的。您需要确保映射列表(y)的排列顺序也从最小到最大。

ind = list(x[i][0] for i in range(len(x)))

lookup = set()
ind = [x for x in ind if x not in lookup and lookup.add(x) is None]

for i in range(len(x)):
           c = ind.index(x[i][0])
           x[i][0] = y[c]

print(x)

输出:

array([['1', 'something'],
       ['1', 'more'],
       ['2', 'and more'],
       ['3', 'and so on'],
       ['3', 'etc..']], dtype='<U11')

答案 3 :(得分:0)

如果您想像现在一样继续使用for循环并利用y列表,可以执行以下操作:

import numpy as np

x = np.array([[2, 'something'], [2, 'more'], [6, 'and more'],
              [11, 'and so on'], [11, 'etc..']])
y = [1, 2, 3]

y_index = 0
for i in range(0, x.shape[0] - 1):
  if x[i+1][0] != x[i][0]:
    x[i][0] = y[y_index]
    y_index += 1
  else:
    x[i][0] = y[y_index]
x[-1][0] = y[y_index] # Set last index

print(x)

输出:

[['1' 'something']
 ['1' 'more']
 ['2' 'and more']
 ['3' 'and so on']
 ['3' 'etc..']]