Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/278.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 有没有一种快速的方法来获取列表中的所有相邻元素?_Python_Python 3.x_Numpy - Fatal编程技术网

Python 有没有一种快速的方法来获取列表中的所有相邻元素?

Python 有没有一种快速的方法来获取列表中的所有相邻元素?,python,python-3.x,numpy,Python,Python 3.x,Numpy,例如,我有一个列表(它也可以是numpy.array或其他任何东西,我只是想知道一个更快的方法,我不关心数据类型)['a'、'b'、'c'、'd'],我想得到['ab'、'bc'、'cd'] 当然有一个简单的解决方案,例如: letters = list('abcdefghijk') my_list = [letters[i:i+2] for i in range(len(letters)-1)] 而my_列表是: [['a', 'b'], ['b', 'c'], ['c', 'd'],

例如,我有一个
列表
(它也可以是
numpy.array
或其他任何东西,我只是想知道一个更快的方法,我不关心数据类型)
['a'、'b'、'c'、'd']
,我想得到
['ab'、'bc'、'cd']

当然有一个简单的解决方案,例如:

letters = list('abcdefghijk')
my_list = [letters[i:i+2] for i in range(len(letters)-1)]
my_列表
是:

[['a', 'b'],
 ['b', 'c'],
 ['c', 'd'],
 ['d', 'e'],
 ['e', 'f'],
 ['f', 'g'],
 ['g', 'h'],
 ['h', 'i'],
 ['i', 'j'],
 ['j', 'k']]
但我想知道有没有更快的方法通过
numpy
或其他什么来实现这一点,因为我想用相对较大的数据来实现这一点,因此简单的
for
循环可能成本高昂

更新 现在让我总结一下下面的答案。非常感谢@Ehsan和@Andy L给出的答案。我通过下面的代码,用相对较大的数据对他们的所有解决方案进行了非常简单的测试:

import time
import numpy as np
from numba import njit
import matplotlib.pyplot as plt
from numpy.lib.stride_tricks import as_strided

def m1(letters):
    return [letters[i]+letters[i+1] for i in range(len(letters)-1)]

@njit
def m2(letters):
    
    return [letters[i]+letters[i+1] for i in range(len(letters)-1)]

def m3(letters):
    return np.char.add(letters[:-1], letters[1:])

def m4(letters):
    n = len(letters) - 1
    m = np.array(letters[0]).itemsize
    arr = as_strided(letters, shape=(n, 2), strides=(m, m))
    return arr

def test_time(testfunc,args):
    start = time.time()
    testfunc(*args)
    return time.time() - start

# test
ns = [10000, 100000, 1000000, 10000000]
timecost = []
for n in ns:
    input_=np.random.choice(list('abcdefghijklmnopqrstuvwxyz'), size=n)
    cost = [test_time(testfunc, [input_]) for testfunc in [m1, m2, m3,m4]]
    timecost.append(cost)

# result plot
timecost = np.array(timecost)
labels = ['normal','numba.njit','numpy.char.add','numpy.lib.stride_tricks.as_strided']
for i in range(timecost.shape[-1]):
    plt.plot(ns, timecost[:, i], label=labels[i])
plt.legend()
plt.savefig('result.png')
结果是:


结果表明,使用
np.char.add
numba
,在较大数据上的性能确实优于常规方法,但
stride\u tricks
的性能甚至更好:时间成本降低了两个数量级以上。

您可以使用numpy:

np.char.add(letters[:-1],letters[1:])
#['ab' 'bc' 'cd' 'de' 'ef' 'fg' 'gh' 'hi' 'ij' 'jk']
使用numba的另一种方法:

@njit
def m2(letters):
  return [letters[i]+letters[i+1] for i in range(len(letters)-1)]

比较使用
benchit

def m1(letters):
  return [letters[i]+letters[i+1] for i in range(len(letters)-1)]

@njit
def m2(letters):
  return [letters[i]+letters[i+1] for i in range(len(letters)-1)]

def m3(letters):
  return np.char.add(letters[:-1],letters[1:])

in_ = [np.random.choice(list(string.ascii_lowercase),size=n) for n in [100,1000,10000,100000]]
它们看起来都一样(注意:不确定
benchit
是否对Numba进行AOT编译):


您可以使用numpy:

np.char.add(letters[:-1],letters[1:])
#['ab' 'bc' 'cd' 'de' 'ef' 'fg' 'gh' 'hi' 'ij' 'jk']
使用numba的另一种方法:

@njit
def m2(letters):
  return [letters[i]+letters[i+1] for i in range(len(letters)-1)]

比较使用
benchit

def m1(letters):
  return [letters[i]+letters[i+1] for i in range(len(letters)-1)]

@njit
def m2(letters):
  return [letters[i]+letters[i+1] for i in range(len(letters)-1)]

def m3(letters):
  return np.char.add(letters[:-1],letters[1:])

in_ = [np.random.choice(list(string.ascii_lowercase),size=n) for n in [100,1000,10000,100000]]
它们看起来都一样(注意:不确定
benchit
是否对Numba进行AOT编译):


使用
作为从
跨步
库中跨步

from numpy.lib.stride_tricks import as_strided

n = len(letters) - 1
m = np.array(letters[0]).itemsize

arr = as_strided(letters, shape=(n, 2), strides=(m, m))

Out[289]:
array([['a', 'b'],
       ['b', 'c'],
       ['c', 'd'],
       ['d', 'e'],
       ['e', 'f'],
       ['f', 'g'],
       ['g', 'h'],
       ['h', 'i'],
       ['i', 'j'],
       ['j', 'k']], dtype='<U1')
from numpy.lib.stride\u技巧在跨步时导入
n=长度(字母)-1
m=np.array(字母[0]).itemsize
arr=步幅(字母,形状=(n,2),步幅=(m,m))
出[289]:
数组(['a','b'],
['b','c'],
['c','d'],
['d','e'],
['e','f'],
['f','g'],
['g','h'],
['h','i'],
['i','j'],

['j','k']],dtype='使用
as\u-stride
stride\u-tricks

from numpy.lib.stride_tricks import as_strided

n = len(letters) - 1
m = np.array(letters[0]).itemsize

arr = as_strided(letters, shape=(n, 2), strides=(m, m))

Out[289]:
array([['a', 'b'],
       ['b', 'c'],
       ['c', 'd'],
       ['d', 'e'],
       ['e', 'f'],
       ['f', 'g'],
       ['g', 'h'],
       ['h', 'i'],
       ['i', 'j'],
       ['j', 'k']], dtype='<U1')
from numpy.lib.stride\u技巧在跨步时导入
n=长度(字母)-1
m=np.array(字母[0]).itemsize
arr=步幅(字母,形状=(n,2),步幅=(m,m))
出[289]:
数组(['a','b'],
['b','c'],
['c','d'],
['d','e'],
['e','f'],
['f','g'],
['g','h'],
['h','i'],
['i','j'],

['j','k']],dtype='我不在乎数据类型:它们都是字符吗?或者你的意思与浮点数一样吗?@Ehsan我的错。我的意思是它们都是字符,但我可以接受任何类型的容器,如
numpy.array
或其他类型。你想得到
['ab'、'bc'、'cd']
['a'、'b'、['b'、'c'],['c','d'],…
?这是两种不同的格式。@Divakar
['a','b'],['b','c'],['c','d'],…
会更好。我不在乎数据类型:它们都是字符吗?或者你的意思与浮点数一样吗?@Ehsan我的错。我的意思是它们都是字符,但我可以接受任何类型的容器,例如
numpy.array
或其他什么。你想得到
['ab'、'bc'、'cd']
['a'、'b'],['b','c'],['c','d'],…
?这是两种不同的格式。@Divakar
['a','b'],['b','c'],['c','d'],…
会更好。非常感谢!此解决方案工作得更好,时间成本减少了两个数量级以上。我在帖子中更新了时间测试结果。@C.K.回答得好。请注意,这为您提供了一个视图。这就是为什么它基本上如此之快。如果您需要单独更改步幅,这可能会变得很困难ky(例如,两个
'b'
s都指相同的内存)非常感谢!此解决方案效果更好,时间成本减少了两个数量级以上。我在我的帖子中更新了时间测试结果。@C.K.回答得好。请注意,这为您提供了一个视图。这就是为什么它基本上如此快的原因。如果您需要单独更改步幅,这可能会变得棘手(例如,两个
'b'
s都指相同的内存)非常感谢你!我在更大的数据中测试了它,使用
numpy
numba
的两种方法比普通方法工作得更好!非常感谢你!我在更大的数据中测试了它,使用
numpy
numba
的两种方法比普通方法工作得更好!