是否有更好的方法将字符串操作应用于ndarrays而不是迭代它们?我想使用"矢量化"操作,但我只能想到使用map(示例显示)或列表推导.
Arr = numpy.rec.fromrecords(zip(range(5),'as far as i know'.split()),
                            names='name, strings')
print ''.join(map(lambda x: x[0].upper()+'.',Arr['strings']))
=> A.F.A.I.K.
例如,在R语言中,字符串操作也是矢量化的:
> (string <- unlist(strsplit("as far as i know"," ")))
[1] "as"   "far"  "as"   "i"    "know"
> paste(sprintf("%s.",toupper(substr(string,1,1))),collapse="")
[1] "A.F.A.I.K."
Fre*_*Foo 16
是的,最近的NumPy在numpy.char模块中进行了矢量化字符串操作.例如,当你想在字符串数组中找到以B开头的所有字符串时,就是这样
>>> y = np.asarray("B-PER O O B-LOC I-LOC O B-ORG".split())
>>> y
array(['B-PER', 'O', 'O', 'B-LOC', 'I-LOC', 'O', 'B-ORG'], 
      dtype='|S5')
>>> np.char.startswith(y, 'B')
array([ True, False, False,  True, False, False,  True], dtype=bool)
Joe*_*ton 14
更新:请参阅Larsman对此问题的回答:Numpy最近添加了一个numpy.char基本字符串操作模块.
简短回答: Numpy不提供矢量化字符串操作.惯用的方法是做一些事情(Arr你的numpy数组在哪里):
print '.'.join(item.upper() for item in Arr['strings'])
答案很长,这就是为什么numpy不提供矢量化字符串操作:(并且介于两者之间的漫游)
在数据结构方面,一种尺寸并不适合所有情况.
对于来自非特定领域的编程语言的人来说,您的问题可能看起来很奇怪,但对于来自特定领域语言的人来说,这很有意义.
Python为您提供了各种各样的数据结构选择.某些数据结构在某些任务中比其他任务更好.
首先,numpy数组不是python中默认的"hold-all"容器.Python的内置容器非常擅长于它们的设计目标.通常,列表或词典是您想要的.
Numpy ndarray用于同质数据.
简而言之,numpy没有矢量化字符串操作.
ndarrays是一个专门的容器,专注于在尽可能少的内存中存储N维同质的项目组.重点是最大限度地减少内存使用(我有偏见,因为这主要是我需要它们,但它是一种有用的思考方式.).向量化的数学运算只是将事物存储在连续的内存块中的一个很好的副作用.
字符串通常具有不同的长度.
例如['Dog', 'Cat', 'Horse'].Numpy采用类似数据库的方法,要求您为字符串定义长度,但字符串不是固定长度的简单事实有很多含义.
最有用的字符串操作返回可变长度字符串 (例如'.'.join(...)在你的例子中)
那些没有(例如鞋面等)你可以模仿其他操作,如果你想.(例如鞋面粗略(x.view(np.uint8) - 32).view('S1').我不建议你这样做,但你可以...)
作为一个基本的例子:'A' + 'B'收益率'AB'.  'AB'和'A'or的长度不一样'B'.Numpy处理其他事情(例如np.uint8(4) + np.float(3.4)),但字符串的长度比数字更灵活.(数字的"向上转换"和"向下转换"规则非常简单.)
numpy不这样做的另一个原因是焦点在于数值运算.  'A'**2在python中没有特定的定义(你当然可以创建一个字符串类,但它应该是什么?).字符串数组是numpy中的二等公民.它们存在,但大多数操作都没有为它们定义.
Python已经非常擅长处理字符串处理
numpy不尝试提供字符串操作的另一个(实际上是主要的)原因是python已经非常擅长它.
列表是非常灵活的容器.Python有很多非常好的,非常快速的字符串操作.列表推导和生成器表达式相当快,并且它们不会因尝试猜测返回项目的类型或大小而受到任何开销,因为它们并不关心.(他们只是存储一个指向它的指针.)
另外,在python中迭代numpy数组比在python中遍历列表或元组要慢,但对于字符串操作,你最好只使用普通的列表/生成器表达式.(例如print '.'.join(item.upper() for item in Arr['strings'])在你的例子中)更好的是,不要使用numpy数组来存储字符串.如果你有一个带有字符串的结构化数组的单列,这是有道理的,但这就是它.Python为您提供了非常丰富和灵活的数据结构.Numpy数组并不是最重要的,它们是一个专门的案例,而不是一般情况.
另外,请记住,大多数你想用numpy数组做什么
学习Python,而不仅仅是Numpy
我不是想在这里变得厚颜无耻,但使用numpy数组与Matlab或R或IDL等很多东西非常相似.
这是一个熟悉的范例,任何人的第一直觉就是尝试将相同的范例应用于其他语言.
Python不仅仅是numpy.它是一种多范式语言,所以很容易坚持你已经习惯的范式.尝试学习"在python中思考"以及"在numpy中思考".Numpy为python提供了一个特定的范例,但是那里有更多,并且有些范例比其他范式更适合某些任务.
部分原因是熟悉不同数据容器(列表与dicts与元组等)的优缺点,以及不同的编程范例(例如面向对象与功能与程序等).
总而言之,python有几种不同类型的专用数据结构.这使得它与特定于域的语言(如R或Matlab)略有不同,后者具有几种类型的数据结构,但专注于使用一种特定结构执行所有操作.(我对R的经验是有限的,所以我可能在那里错了,但无论如何,这是我对它的印象.无论如何,这对Matlab来说确实如此.)
无论如何,我不是想在这里咆哮,但是我花了很长时间才停止在Matlab中编写Fortran,我花了更长时间才停止在python中编写Matlab.这个漫无边际的答案非常类似于具体的例子,但希望它至少有一点意义,并且有所帮助.
| 归档时间: | 
 | 
| 查看次数: | 12001 次 | 
| 最近记录: |