python - 如果条件为真,则从嵌套列表中删除列表

标签 python pandas

我有一个按时间顺序排列的旅行站点列表:

travel = [[start, stop, mode_of_transport], ...]

其中一些是乘船(mode_of_transport == 'B')。

不幸的是,在您需要之前,船只可能会停在几个港口 离开它 - 那些中间停留与我无关。

因此,我想将多个连续的船停靠点合并为一个 - 保留第一个“B”的 start 端口和 stop 端口(以及 最后一个港口的 mode_of_transportation) - 仅适用于我的旅行数据中的连续 'B'

我编写了一个非常大的函数,如果条件变为真,则基本上删除嵌套列表的一部分,但太大/太慢:

def remove_boat_seg(data):
    # get boat runs to collapse boat segments
    log = []
    description = data
    print(description)
    
    b_segs={}
    b_keys=[]
    for b in b_sets:
        bmin=min(b)
        bmax=max(b)
        b_segs[bmin]=[description[bmin][0],description[bmax][1],'B']
        b_keys.append(bmin)
    tdscr=[]
    for i in range(len(description)):
        if i not in b_inds:
            tdscr.append(description[i])
        elif i not in b_keys:
            continue
        else:
            tdscr.append(b_segs[i])
            msg=b_segs[i]
            if len(msg)>1:
                log.append(msg)
    description=tdscr
    return description

解释/输出

#所有列表的最后一个元素是mode_of_transport #嵌套列表中的每个列表都是完整路线的一段

解释输出1:

  • 查找最后一个元素=“B”的所有段嵌套列表
  • 存储实例编号。
  • 如果所有列表都有 B,则取出第一个列表的第一个元素,然后取出最后一个列表的第二个元素,并将第三个元素添加为 B 并返回。 (即缩短路线)(我正在使用定义为 b_inds 的索引进行检查)

解释输出2:

  • 考虑以上几个方面
  • 比较第一个段与下一个段的模式
  • 我们必须检查是否有 B 模式重复的片段(B 是船),如果它重复,那么我们必须采用该片段的第一个元素以及最后一个片段的第二个和第三个元素,在该片段模式之后变化。
  • 就像在这种情况下输出 2 一样,您可以看到索引 0,1,2 是相同的,而第三个不是 B,因此,对于第一个段,选择第一个元素 3786,因为它是该列表的最后一个元素,其中下一个段模式不是 B 即 USMSY
  • 然后您会看到模式 B 的片段再次排在最后和倒数第三位。我们没有做任何事情,因为他们的下一段不是 B

我想减少这个功能,想让它变得很短。因为我的时间有限。

最佳答案

您可以按传输模式对数据进行分组,并针对连续的“B”段修改它们:

from itertools import groupby

# testcase 2
data = [['3786', 'AEJEA', 'B'], ['AEJEA', 'GBLGP', 'B'], ['GBLGP', 'USMSY', 'B'], 
        ['USMSY', 'DNTS', 'K'], ['DNTS', 'NEWORL_LA', 'K'], ['NEWORL_LA', 'LBEACH_CA', 'K'],
        ['LBEACH_CA', 'USLGB', 'K'], ['USLGB', 'CNSHG', 'B'], ['CNSHG', 'EJ00', 'K'], 
        ['EJ00', '354B', 'B']]
 
result = []

# group by the last element ("transport_mode") of inner elements
# and combine consecutive "B"oat stops into one
for grp,val in groupby (data, lambda x:x[-1]):
    # if B create one merged elements
    if grp == "B":
        vals = list(val)
        # use the first B's 1st value and
        # 2nd to last value of last B
        r = [vals[0][0], *vals[-1][1:]]
        result.append(r)

    # take all elements
    else:
        result.extend(val)

print (result)
# print your current result for testcase 2
print( [['3786', 'USMSY', 'B'], ['USMSY', 'DNTS', 'K'], ['DNTS', 'NEWORL_LA', 'K'], 
        ['NEWORL_LA', 'LBEACH_CA', 'K'], ['LBEACH_CA', 'USLGB', 'K'],
        ['USLGB', 'CNSHG', 'B'], ['CNSHG', 'EJ00', 'K'], ['EJ00', '354B', 'B']])

输出:

[['3786', 'USMSY', 'B'], ['USMSY', 'DNTS', 'K'], ['DNTS', 'NEWORL_LA', 'K'], ['NEWORL_LA', 'LBEACH_CA', 'K'], ['LBEACH_CA', 'USLGB', 'K'], ['USLGB', 'CNSHG', 'B'], ['CNSHG', 'EJ00', 'K'], ['EJ00', '354B', 'B']]
[['3786', 'USMSY', 'B'], ['USMSY', 'DNTS', 'K'], ['DNTS', 'NEWORL_LA', 'K'], ['NEWORL_LA', 'LBEACH_CA', 'K'], ['LBEACH_CA', 'USLGB', 'K'], ['USLGB', 'CNSHG', 'B'], ['CNSHG', 'EJ00', 'K'], ['EJ00', '354B', 'B']]

关于python - 如果条件为真,则从嵌套列表中删除列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70709510/

相关文章:

python - 从构造函数中选择枚举值?

python - 使用 pandas 中列的所有唯一值从数据框创建折线图?

python - qPython - kdb响应数据的类型转换

python - 构建 JSON 编码的字典 - python

python - 使用openCV和numpy进行图像处理。尝试返回没有红色的图像

javascript - 理解js代码表达

python - 使用 Dask 在大型集合上映射可变执行时间的函数

python - Pandas 删除一个数据框中的行,这些行与另一个数据框的列中的行共享一个公共(public)值

python - 在 matplotlib 线图上向 x 轴和图例添加月份

python - Kivy 不同小部件和布局类之间的属性和通信