【发布时间】:2022-01-20 12:56:36
【问题描述】:
我一直在研究 numpy 的搜索和替换,并且想知道如何为混合的 numpy 数组执行更 Pythonic 的搜索和替换方式。
这是一个使用 for 循环的搜索和替换的工作示例,它看起来不太像 Python。如果数组仅由字符串组成,那么 np.char.replace() 函数当然可以工作;代码中也有一个示例。
我想知道还有哪些其他方法可能有效;展平数组,使用另一个包,或将 numpy 数组转换为其他内容,然后将其转换回其他内容。
这是一个小例子;有一个更大的数组要处理(100K+ 个元素),因此获得更好的性能会很棒。
import numpy as np
# numpy array with ints, strings, and floats
a=np.array([(1001,'Thing Alpha Red',0.99),
(1002,'Thing Bravo Orange',1.29),
(1003,'Thing Charlie Yellow',3.49),
(1004,'Some Random Color',10.99),
(99999,'Thing Delta',4.99)],dtype=object)
# This is a list
a_lookup=[('Alpha','Apple'),('Bravo','Bus'),('Charlie','Car'),('Delta','Dog')]
# Make a copy of a, for later comparison
c=np.copy(a)
# This replaces every substring 'Thing' with 'Box'
# Most unpythonic!
for each in c:
each[1]=each[1].replace('Thing','Box')
print('a original:')
print(a)
print('')
print('c replaced, using loop:')
print(c)
# Now look through a_lookup, and replace from that list
# Even more unpythonic; two for loops
for each in c:
# Get the string
temp=each[1]
# loop through the lookup table, doing a replacement
for each_item in a_lookup:
if(each[1].find(each_item[0])>=0):
temp=temp.replace(each_item[0],each_item[1])
break
each[1]=temp
print('')
print('c, replacing elements from lookup table, using loop:')
print(c)
# This is more pythonic, but will not work on mixed numpy array
print(' ')
print('Using numpy replace on array of *only* strings')
d=np.array(['Box Alpha', 'Box Bravo', 'Box Charlie', 'Box Delta'])
print(d)
print('')
e=np.char.replace(d,'Box','Container')
print(e)
【问题讨论】:
-
这些东西有什么“unpythonic”?它们是有效的、工作的python。诚然,它们都可以与列表列表一起工作,也许更好。您的数组是
objectdtype,因此它像在列表中一样存储引用。你正在做一个字符串操作。您也许可以使用re一次对字符串进行所有替换,但我不熟悉该模块。这不是使用快速编译的 numpy 方法进行的数值计算。 -
我认为'for'循环不被认为是优雅的! atomh33ls 有一个简洁的解决方案。如果最初发布的内容被认为是好的,我可以接受,但似乎 python 总有一个巧妙的技巧。例如,atomh33ls 的答案,至少对于第一个子字符串替换。
-
循环(列表推导)在处理 python 列表、字典和字符串时很常见。
numpy数组最好与 tbeir 自己的方法(在编译代码中循环)一起使用。但是有些东西不适合该模型 - 例如带有字符串的对象 dtype。
标签: python arrays numpy replace