Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.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_List_Numpy_Slice - Fatal编程技术网

Python 使用不同长度切片子列表

Python 使用不同长度切片子列表,python,list,numpy,slice,Python,List,Numpy,Slice,我有一份清单。每个子列表的长度在1到100之间。每个子列表在一组数据中的不同时间包含一个粒子ID。我想在给定的时间形成所有粒子ID的列表。为此,我可以使用以下方法: list = [[1,2,3,4,5],[2,6,7,8],[1,3,6,7,8]] list2 = [item[0] for item in list] 列表2将包含列表中每个子列表的第一个元素。我不仅要对第一个元素执行此操作,还要对1到100之间的每个元素执行此操作。我的问题是元素编号100(或66或77或其他

我有一份清单。每个子列表的长度在1到100之间。每个子列表在一组数据中的不同时间包含一个粒子ID。我想在给定的时间形成所有粒子ID的列表。为此,我可以使用以下方法:

    list = [[1,2,3,4,5],[2,6,7,8],[1,3,6,7,8]]
    list2 = [item[0] for item in list]
列表2将包含列表中每个子列表的第一个元素。我不仅要对第一个元素执行此操作,还要对1到100之间的每个元素执行此操作。我的问题是元素编号100(或66或77或其他)并不存在于每个子列表中

是否有创建列表列表的方法,其中每个子列表都是给定时间内所有粒子ID的列表


我曾经考虑过尝试使用numpy数组来解决这个问题,就好像列表的长度都是一样的,这将是微不足道的。我曾尝试在每个列表的末尾添加-1,使它们的长度相同,然后掩盖负数,但到目前为止,这对我并不奏效。我将在给定时间使用ID列表分割另一个单独的数组:

    pos = pos[satIDs]
--更新--


如果您想使用
一行forloop
并在
数组中执行此操作,可以执行以下操作:

list2 = [[item[i] for item in list if len(item) > i] for i in range(0, 100)]
list2 = [{list.index(item): item[i] for item in list if len(item) > i} for i in range(0, 100)]
如果你想知道哪个id来自哪个列表,你可以这样做:

list2 = [[item[i] for item in list if len(item) > i] for i in range(0, 100)]
list2 = [{list.index(item): item[i] for item in list if len(item) > i} for i in range(0, 100)]
清单2是这样的:

[{0: 1, 1: 2, 2: 1}, {0: 2, 1: 6, 2: 3}, {0: 3, 1: 7, 2: 6}, {0: 4, 1: 8, 2: 7},
 {0: 5, 2: 8}, {}, {}, ... ]

您可以将
numpy.nan
附加到短列表中,然后创建一个numpy数组

import numpy
import itertools

lst = [[1,2,3,4,5],[2,6,7,8],[1,3,6,7,8,9]]
arr = numpy.array(list(itertools.izip_longest(*lst, fillvalue=numpy.nan)))
之后,您可以像往常一样使用numpy切片

print arr
print arr[1, :]   # [2, 6, 3]
print arr[4, :]   # [5, nan, 8]
print arr[5, :]   # [nan, nan, 9]
你可以用。这将
将列表压缩到一起,并在其中一个列表用尽时插入
None

>>> lst = [[1,2,3,4,5],['A','B','C'],['a','b','c','d','e','f','g']]    
>>> list(itertools.zip_longest(*lst))
[(1, 'A', 'a'),
 (2, 'B', 'b'),
 (3, 'C', 'c'),
 (4, None, 'd'),
 (5, None, 'e'),
 (None, None, 'f'),
 (None, None, 'g')]
如果不需要
None
元素,可以将其过滤掉:

>>> [[x for x in sublist if x is not None] for sublist in itertools.zip_longest(*lst)]
[[1, 'A', 'a'], [2, 'B', 'b'], [3, 'C', 'c'], [4, 'd'], [5, 'e'], ['f'], ['g']]
方法#1

可以建议使用一种几乎矢量化的方法,根据新的顺序和拆分创建ID,如下所示-

def position_based_slice(L):

    # Get lengths of each element in input list
    lens = np.array([len(item) for item in L])

    # Form ID array that has *ramping* IDs within an element starting from 0
    # and restarts with a new element at 0
    id_arr = np.ones(lens.sum(),int)
    id_arr[lens[:-1].cumsum()] = -lens[:-1]+1

    # Get order maintained sorted indices for sorting flattened version of list
    ids = np.argsort(id_arr.cumsum(),kind='mergesort')

    # Get sorted version and split at boundaries decided by lengths of ids
    vals = np.take(np.concatenate(L),ids)
    cut_idx = np.where(np.diff(ids)<0)[0]+1
    return np.split(vals,cut_idx)
方法#2

下面是另一种创建
2D
数组的方法,它更容易索引和跟踪原始输入元素。这使用NumPy广播和布尔索引。实现看起来像这样-

def position_based_slice_2Dgrid(L):

    # Get lengths of each element in input list
    lens = np.array([len(item) for item in L])

    # Create a mask of valid places in a 2D grid mapped version of list
    mask = lens[:,None] > np.arange(lens.max())
    out = np.full(mask.shape,-1,dtype=int)
    out[mask] = np.concatenate(L)
    return out
样本运行-

In [76]: input_list = [[1,2,3,4,5],[2,6,7,8],[1,3,6,7,8],[3,2]]

In [77]: position_based_slice(input_list)
Out[77]: 
[array([1, 2, 1, 3]), # input_list[ID=0]
 array([2, 6, 3, 2]), # input_list[ID=1]
 array([3, 7, 6]),    # input_list[ID=2]
 array([4, 8, 7]),    # input_list[ID=3]
 array([5, 8])]       # input_list[ID=4]
In [126]: input_list = [[1,2,3,4,5],[2,6,7,8],[1,3,6,7,8],[3,2]]

In [127]: position_based_slice_2Dgrid(input_list)
Out[127]: 
array([[ 1,  2,  3,  4,  5],
       [ 2,  6,  7,  8, -1],
       [ 1,  3,  6,  7,  8],
       [ 3,  2, -1, -1, -1]])

所以,现在输出的每一列都将对应于基于ID的输出。

是否要使用一行for循环来执行此操作?或者任何for循环都可以?任何循环都可以,但是数据集非常大,因此速度可能会成为一个问题。“屏蔽负数,但这对我来说还不起作用”-这对你来说怎么不起作用?非常感谢,还有没有一种方法可以跟踪func(x)中的哪个元素来自哪个列表,例如,一个附加列表,上面写着(对于func(4)),5来自子列表0,8来自子列表2?…使用
lambda
然后将其分配给名称有什么意义?只需使用
def func(x):返回[line[x]…]
@Jack已更新。元组中的第一个元素是value,第二个是numbersublist@Bakuriu同意你的看法如果我用这种方式做一个切片,我能告诉我切片数组中的每个元素来自哪一行吗?也就是说,它会保留nan吗?当然可以。每当你跑过任何列表的末尾时,该条目就会变成一个
nan。但是我是否可以使用切片数组,例如x=[nan,nan,9]来执行另一个数组的切片,数据[x]-这不会给我一个错误吗?索引器:用作索引的数组必须是整数(或布尔)类型您正在尝试将结果列表用作索引?抱歉,我没有在您的帖子中读到这一点。