2015-11-04 51 views
2

我有一个numpy的阵列,其具有数百其是大写字母的元素,在没有特定的顺序如何使用字典翻译/替换数组的元素?

import numpy as np 
abc_array = np.array(['B', 'D', 'A', 'F', 'H', 'I', 'Z', 'J', ...]) 

在此numpy.ndarray每个元素是一个numpy.string_

我也有一个“翻译词典”,以键/值对,这样的大写字母对应于一个城市

transdict = {'A': 'Adelaide', 'B': 'Bombay', 'C': 'Cologne',...} 

只有26个对字典中的transdict,但也有数以百计的信件在numpy数组中,我必须翻译。

什么是最有效的方法来做到这一点?

我考虑过使用numpy.core.defchararray.replace(a, old, new, count=None)[source],但是这会返回ValueError,因为numpy数组的大小与字典键/值不同。

AttributeError: 'numpy.ndarray' object has no attribute 'translate'

+0

您是否尝试过任何有效的代码,无论它*效率低下?样本数据的预期输出是什么? – Divakar

+0

@Divakar实际上,我最好的猜测是使用'numpy.core.defchararray.replace()',但这是行不通的。所以是的,我不知道该怎么做。 – ShanZhengYang

+0

对于'old',你需要使用'transdict.keys()',对于'new'你需要使用'transdict.values()',然后'.replace(abc_array,old,new)'应该可以工作 –

回答

3

请问这个怎么办?有时候,纯Python是处理这种事情的好方法。下面构建一个翻译列表(很容易转换回numpy数组)和连接的输出。

import numpy as np 
abc_array = np.array(['B', 'D', 'A', 'F', 'H', 'I', 'Z', 'J']) 

transdict = {'A': 'Adelaide', 
      'B': 'Bombay', 
      'C': 'Cologne', 
      'D': 'Dresden', 
      'E': 'Erlangen', 
      'F': 'Formosa', 
      'G': 'Gdansk', 
      'H': 'Hague', 
      'I': 'Inchon', 
      'J': 'Jakarta', 
      'Z': 'Zambia' 
} 

phoenetic = [transdict[letter] for letter in abc_array] 
print ' '.join(phoenetic) 

从这个输出是:

Bombay Dresden Adelaide Formosa Hague Inchon Zambia Jakarta 
+0

我认为你是对的;一个Python for循环是要走的路。 – ShanZhengYang

+0

很好......但你可能会等待其他想法,特别是纯粹的numpy。一旦你有一个好的解决方案,不要忘记“接受”你的最爱。 – Prune

5

随着蛮力NumPy broadcasting -

idx = np.nonzero(transdict.keys() == abc_array[:,None])[1] 
out = np.asarray(transdict.values())[idx] 

通过基于np.searchsorted搜索和索引 -

sort_idx = np.argsort(transdict.keys()) 
idx = np.searchsorted(transdict.keys(),abc_array,sorter = sort_idx) 
out = np.asarray(transdict.values())[sort_idx][idx] 

样品运行 -

In [1]: abc_array = np.array(['B', 'D', 'A', 'B', 'D', 'A', 'C']) 
    ...: transdict = {'A': 'Adelaide', 'B': 'Bombay', 'C': 'Cologne', 'D': 'Delhi'} 
    ...: 

In [2]: idx = np.nonzero(transdict.keys() == abc_array[:,None])[1] 
    ...: out = np.asarray(transdict.values())[idx] 
    ...: 

In [3]: out 
Out[3]: 
array(['Bombay', 'Delhi', 'Adelaide', 'Bombay', 'Delhi', 'Adelaide', 
     'Cologne'], 
     dtype='|S8') 

In [4]: sort_idx = np.argsort(transdict.keys()) 
    ...: idx = np.searchsorted(transdict.keys(),abc_array,sorter = sort_idx) 
    ...: out = np.asarray(transdict.values())[sort_idx][idx] 
    ...: 

In [5]: out 
Out[5]: 
array(['Bombay', 'Delhi', 'Adelaide', 'Bombay', 'Delhi', 'Adelaide', 
     'Cologne'], 
     dtype='|S8') 
+0

难道你不只是用searchsorted回答另一个dicitonary问题吗? :) – hpaulj

+0

@hpaulj是不是很有趣!? ;)* NumPythonic *一切:) – Divakar

+0

抓住我的东西是惊喜。第一种方法将在大量数据结构上失败并显示无用的错误消息。据我可以告诉'=='开始返回超过某些限制而不是广播的'True' /'False'。 – Annan