了解Python中两个列表之间是否存在公共项的最简单方法?

2024-05-29 10:07:56 发布

您现在位置:Python中文网/ 问答频道 /正文

我目前正在python上开发2个数据帧。我有一个大数据帧(135000个观察值),我正在努力寻找一个优化算法,使我能够更有效地执行微积分。我的第一个数据库df来自食品,在df.additives列中的每个观察值都有一个list。它包含产品中的所有添加剂。例如:

df.additives[0]=['milkfat-and-nonfat-milk','e200','and-nonfat-milk','milk','natural-flavor','flavor','mono-diglycerides','diglycerides','guar-gum','e412']

第二个数据帧是每个不健康添加剂的列表,它们包含在一个名为

high=['e202', 'e407', 'e450', 'e250', 'e341', 'e211', 'e621', 'e200', 'e452', 'e481', 'e340', 'e223', 'e451', 'e338', 'e220', 'e252', 'e339', 'e212', 'e224', 'e491', 'e222', 'e251', 'e407a', 'e492', 'e221', 'e473', 'e210', 'e343', 'e482', 'e228', 'e155', 'e243', 'e226', 'e494', 'e459', 'e493', 'e213']

我的目标是知道df.additives[i]中的element是否与列表high匹配。如果是True,我在名为df.high的伪列中将值1分配给该行。最终目标是识别哪些食品含有不健康的添加剂,以便日后分析(比较等) 我的代码适用于少量产品,但是每次我尝试将其应用于我的完整数据集时,代码的运行时间无限长,远远超过1小时,仅占我样本的10%(大约10000)。我知道我的算法架构可能不适合big data样本。我想知道我们是否可以对其进行优化,使现代pc可以在10分钟内执行此命令?或者我是否使用了一种未经优化的策略

下面是我正在使用的代码:

df['high']= np.zeros(len(df)) # create a dummy column with only zeros at first

def common_member(a, b): # define a fct that give True if there is at least one common elelment
    a_set = set(a)
    b_set = set(b)
    if (a_set & b_set):
        return True 
    else:
        return False
i=0
while i<len(df.additives):
    
    if common_member(df.additives.iloc[i],high)==True:
        df['high'][i]=1 # change the dummy to 1 in the given row
    i=i+1

同样有效但未针对大样本进行优化的备选方案:

for row in range(len(df.additives)):
    list_row = set(df.additives.iloc[row])
    if (list_row & set(high)):
        df['high'][row]=1

我尝试了在堆栈溢出上看到的解决方案来解决一个近似的问题,但是它对我的情况不起作用(假人始终保持在0):

def common_item(l1, l2):
    return list(set(l1) & set(l2))
i=0
while i<len(df.additives):
    if common_item(df.additives.iloc[i],high)==True:
        df['high'][i]=1
    i=i+1

感谢您的支持


Tags: 数据代码truedflenifcommonlist
1条回答
网友
1楼 · 发布于 2024-05-29 10:07:56

主要是,你的问题是在熊猫身上迭代东西可能非常慢。可能是逐行分配导致熊猫必须每行克隆一次整个数据帧

那么,在用df.additives.values迭代之前,让我们先把所有的值都取出来,看看结果如何,然后我们可以创建一列新的布尔值

import random
import string
import time

import pandas as pd

start_time = time.time()

high=set(['e202', 'e407', 'e450', 'e250', 'e341', 'e211', 'e621', 'e200', 'e452', 'e481', 'e340', 'e223', 'e451', 'e338', 'e220', 'e252', 'e339', 'e212', 'e224', 'e491', 'e222', 'e251', 'e407a', 'e492', 'e221', 'e473', 'e210', 'e343', 'e482', 'e228', 'e155', 'e243', 'e226', 'e494', 'e459', 'e493', 'e213'])

def make_ingredients():
    return [''.join(random.choices(string.ascii_uppercase + string.digits, k=4)) for i in range(1, 100)]

sample_ingredients = make_ingredients()
sample_ingredients.append('e202')

list_of_ingredients = [make_ingredients() for i in range(1, 350000)]
list_of_ingredients.append(sample_ingredients)

checkpoint_time = time.time()
checkpoint_delta = checkpoint_time - start_time
checkpoint_string = time.strftime("%H:%M:%S", time.gmtime(checkpoint_delta))
print(f'Time to create junk data: {checkpoint_string}')

df = pd.DataFrame({'id': range(len(list_of_ingredients)), 'additives': list_of_ingredients})

df["high"] = [len(set(additives).intersection(high)) > 0 for additives in df.additives.values]

print(df)

intersection_delta = time.time() - checkpoint_time
intersection_string = time.strftime("%H:%M:%S", time.gmtime(intersection_delta))
print(f'Time to check for intersections: {intersection_string}')

在我的笔记本电脑上,这会产生:

Time to create junk data: 00:01:21
            id                                          additives   high
0            0  [GBI5, 5ZH5, AUSE, GU8C, Z5WJ, NU56, GJ1M, 8EN...  False
1            1  [JPC7, PZ3P, 7PV1, DP6O, 4OZ9, 3UN0, 3116, MXW...  False
2            2  [1RJP, BG6O, PMI9, Y9PD, W9NF, 25A8, QB6C, 490...  False
3            3  [3WCC, 6682, O0BY, JT52, AG8H, 0HKC, VV7N, 5YU...  False
4            4  [ZOGO, 6V4B, NBJZ, 0U93, 0P2G, 8TIH, B15Y, A7I...  False
...        ...                                                ...    ...
349995  349995  [5G6W, QRPL, D3ZH, XIA8, GG8X, H401, 7RU3, 8VY...  False
349996  349996  [ZLJJ, Q8YG, NCE8, ULBT, 6VFU, B24E, EYU5, SM0...  False
349997  349997  [4UJ0, HYD3, UPQ4, 1H8F, 2MKR, LSAM, M7KC, CWF...  False
349998  349998  [LFER, 44CC, 214W, FXU4, 3F4V, UCRD, 8O8F, SBD...  False
349999  349999  [KZJY, 28MA, TDUL, ANBM, SD1A, 69FT, 9TYY, VTF...   True

[350000 rows x 3 columns]
Time to check for intersections: 00:00:03

是的,检查设置的交叉口需要三秒的时间。:)

相关问题 更多 >

    热门问题