【问题标题】:Replace values of a numpy array by values from another numpy array用另一个 numpy 数组中的值替换 numpy 数组的值
【发布时间】:2015-03-28 18:23:05
【问题描述】:

我有一个 1000 * 1000 的 numpy 数组,其中包含 100 万个值,创建如下:

>>import numpy as np
>>data = np.loadtxt('space_data.txt')
>> print (data)
>>[[ 13.  15.  15. ...,  15.  15.  16.]
   [ 14.  13.  14. ...,  13.  15.  16.]
   [ 16.  13.  13. ...,  13.  15.  17.]
   ..., 
   [ 14.   15.  14. ...,  14.  14.  13.]
   [ 15.   15.  16. ...,  16.  15.  14.]
   [ 14.   13.  16. ...,  16.  16.  16.]]

我有另一个 numpy 数组,它有 2 列,如下所示:

>> print(key)
>>[[ 10.,   S],
   [ 11.,   S],
   [ 12.,   S],
   [ 13.,   M],
   [ 14.,   L],
   [ 15.,   S],
   [ 16.,   S],
   ...,
   [ 92.,   XL],
   [ 93.,   M],
   [ 94.,   XL],
   [ 95.,   S]]

我基本上想要的是将数据数组的每个元素替换为键数组第二列中的相应元素,如下所示..

>> print(data)
>>[[ M  S  S ...,  S  S  S]
   [ L   M  L ...,  M  S  S]
   [ S   M  M ...,  M  S  XL]
   ..., 
   [ L   S  L ...,  L  L  M]
   [ S   S  S ...,  S  S  L]
   [ L   M  S ...,  S  S  S]]

【问题讨论】:

  • 请更正data 的代码 sn-p,因为它是错误的(缺少逗号)。这可能会使该数据类型的其他用户感到困惑。
  • 是 S、M、L ... 变量名还是字符串?
  • 好吧,如果 data 是一个 numpy 浮点数组,你不能用字符串替换它的元素,所以你需要创建另一个列表
  • @ha9u63ar..我直接从终端复制了这个..我打印了数组并且没有逗号..
  • @Amistad 同时发布 NumPy 数组的 repr 版本:print(repr(data))

标签: python numpy


【解决方案1】:

在 Python 中,字典是从键映射到值的自然选择。 NumPy 有 没有直接等效的字典。但它确实有可以进行快速整数索引的数组。例如,

In [153]: keyarray = np.array(['S','M','L','XL'])

In [158]: data = np.array([[0,2,1], [1,3,2]])

In [159]: keyarray[data]
Out[159]: 
array([['S', 'L', 'M'],
       ['M', 'XL', 'L']], 
      dtype='|S2')

因此,如果我们可以将您的 key 数组按摩成如下所示:

In [161]: keyarray
Out[161]: 
array(['', '', '', '', '', '', '', '', '', '', 'S', 'S', 'S', 'M', 'L',
       'S', 'S', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
       '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
       '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
       '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
       '', '', '', '', '', '', '', '', '', '', 'XL', 'M', 'XL', 'S'], 
      dtype='|S32')

所以在keyarray[10] 等于S 的意义上,10 映射到“S”,依此类推:

In [162]: keyarray[10]
Out[162]: 'S'

然后我们可以使用keyarray[data] 产生所需的结果。


import numpy as np

data = np.array( [[ 13.,   15.,  15.,  15.,  15.,  16.],
                  [ 14.,   13.,  14.,  13.,  15.,  16.],
                  [ 16.,   13.,  13.,  13.,  15.,  17.],
                  [ 14.,   15.,  14.,  14.,  14.,  13.],
                  [ 15.,   15 ,  16.,  16.,  15.,  14.],
                  [ 14.,   13.,  16.,  16.,  16.,  16.]])

key = np.array([[ 10., 'S'],
                [ 11., 'S'],
                [ 12., 'S'],
                [ 13., 'M'],
                [ 14., 'L'],
                [ 15., 'S'],
                [ 16., 'S'],
                [ 17., 'XL'],
                [ 92., 'XL'],
                [ 93., 'M'],
                [ 94., 'XL'],
                [ 95., 'S']])

idx = np.array(key[:,0], dtype=float).astype(int)
n = idx.max()+1
keyarray = np.empty(n, dtype=key[:,1].dtype)
keyarray[:] = ''
keyarray[idx] = key[:,1]

data = data.astype('int')
print(keyarray[data])

产量

[['M' 'S' 'S' 'S' 'S' 'S']
 ['L' 'M' 'L' 'M' 'S' 'S']
 ['S' 'M' 'M' 'M' 'S' 'XL']
 ['L' 'S' 'L' 'L' 'L' 'M']
 ['S' 'S' 'S' 'S' 'S' 'L']
 ['L' 'M' 'S' 'S' 'S' 'S']]

注意data = data.astype('int') 假设data 中的浮点数可以唯一 映射到ints。您的数据似乎就是这种情况,但对于任意浮点数并非如此。例如,astype('int') 将 1.0 和 1.5 都映射到 1。

In [167]: np.array([1.0, 1.5]).astype('int')
Out[167]: array([1, 1])

【讨论】:

  • 这太棒了!!非常感谢,这正是我想要的。有很多使用“for”循环的实现,但这确实是 numpythonic。
  • 哇!这真太了不起了。这是一个非常简洁的解决方案。谢谢!
【解决方案2】:

一种非向量化的线性方法是在这里使用字典:

dct = dict(keys)
# new array is required if dtype is different or it it cannot be casted
new_array = np.empty(data.shape, dtype=str)
for index in np.arange(data.size):
    index = np.unravel_index(index, data.shape)
    new_array[index] = dct[data[index]] 

【讨论】:

    【解决方案3】:
    import numpy as np
    
    data = np.array([[ 13.,  15.,  15.],
       [ 14.,  13.,  14. ],
       [ 16.,  13.,  13. ]])
    
    key = [[ 10.,   'S'],
       [ 11.,   'S'],
       [ 12.,   'S'],
       [ 13.,   'M'],
       [ 14.,   'L'],
       [ 15.,   'S'],
       [ 16.,   'S']]
    
    data2 = np.zeros(data.shape, dtype=str)
    
    for k in key:
        data2[data == k[0]] = k[1]
    

    【讨论】:

    • 如果key 数组中的项目数量不是很大,这应该足够快,但如果key 的大小增加,则会是二次方。
    • 确实,看起来 key 应该有 86 个条目可能......否则可能是最快的
    【解决方案4】:
    # Create a dataframe out of your 'data' array and make a dictionary out of your 'key' array. 
    import numpy as np
    import pandas as pd
    
    data = np.array([[ 13.,  15.,  15.],
                   [ 14.,  13.,  14. ],
                   [ 16.,  13.,  13. ]])
    data_df = pd.DataFrame(data)
    key  = dict({10 : 'S',11 : 'S', 12 : 'S', 13 : 'M',14:'L',15:'S',16:'S'})
    # Replace the values in newly created dataframe and convert that into array.
    data_df.replace(key,inplace = True)
    
    data = np.array(data_df)
    print(data)
    

    这将是输出:

    [['M' 'S' 'S']
    ['L' 'M' 'L']
    ['S' 'M' 'M']]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-09-21
      • 2020-03-18
      • 2013-09-11
      • 1970-01-01
      • 2016-02-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多