#python #pyspark
#python #pyspark
Вопрос:
Я хочу объединить два списка в python, чтобы отфильтровать этот полученный список.
У меня есть следующий фрейм данных df:
--- --------
|v1 | v2 | v |
--- --------
| 2| 4| 24|
| 4| 2| 42|
| 1| 1| 11|
| 1| 3| 13|
| 2| 2| 22|
--- ---- ---
И у меня есть две переменные brodcast (collectAsMap):
- t1:
{'3': ['4'], '1': ['2', '4', '3'], '2': ['3', '4']}
- t2:
{'3': ['4'], '5': ['6'], '1': ['2']}
Я попробовал следующее, чтобы отфильтровать и объединить список
merge_udf = udf(merge, ArrayType(StringType()))
df = df.distinct().withColumn('MergeList', merge_udf(df.v1, df.v2)
где:
"""merge two lists in one list"""
def merge2List(listA, listB):
merge = [(itemA itemB) for itemA in listA for itemB in listB]
return merge
"""merge the entry of two entries of dataframes"""
def merge(x, y):
listA = t1.value.get(x)
if(listA is None):
listA = []
listA.append(x)
listB = t2.value.get(y)
if(listB is None):
listB = []
listB.append(y)
m = merge2List(listA, listB)
return m
Полученный результат следующий:
--- --------- ------------
|v1 |v2 | MergeList|
--- --------- ------------
| 2| 4| [34, 44]|
| 4| 2| [42]|
| 1| 1|[22, 42, 32]|
| 1| 3|[24, 44, 34]|
| 2| 2| [32, 42]|
--- --------- ------------
У меня есть переменная brodcast t3, где print(list(t3.value.keys()))
выдает ['24', '42', '11', '13', '22']
Теперь я хочу отфильтровать элемент в каждом списке в столбце списка слияния. Таким образом, я создаю следующую функцию и обновляю функцию merge2List:
def filterList(v):
vert = list(t3.value.keys())
if(v in vert):
return True
return False
"""merge two lists in one list"""
def merge2List(listA, listB):
merge = [(itemA itemB) for itemA in listA for itemB in listB]
filteredList = filter(filterList, merge)
return filteredList
Возникает следующее исключение:
_pickle.PicklingError: Can't pickle <function filterList at 0x2b2fb1aa6840>: attribute lookup filterList on __main__ failed
Может кто-нибудь помочь определить, где моя ошибка?
Ответ №1:
Поскольку filter вычисляется лениво, pickle не может прочитать значения. Потому что они еще не существуют. Она возвращает итератор. Попробуйте:
filtered = filter(m_func, m_list)
pickle.dumps(list(filtered))
Комментарии:
1. Исключение не возникает, но я получаю во всех столбцах списка слияний следующие странные значения:
[-128, 3, 93, 113...]
2. @moudi позвольте мне проверить, есть ли другая ошибка.
3. @moudi я ничего не смог найти. не могли бы вы попробовать печатать до и после фильтра.
4.
print("n=================filter==============",pickle.dumps(list(filteredList)))
печатает:` ================= фильтр============== b ‘ x80 x03] q x00X x02 x00 x0042q x01a.»5.
pickle.loads(b'x80x03]qx00Xx02x00x00x0042qx01a.')
ВОЗВРАТ['42']
Ответ №2:
Попробуйте:
pickle.loads(pickle.dumps(list(filteredList)))
Ответ №3:
Оба приведенных выше ответа верны. Но я справляюсь следующим образом, чтобы решить проблему:
def merge2List(listA, listB):
merge = [(itemA itemB) for itemA in listA for itemB in listB]
filteredList = filter(lambda x: x in list(t3.value.keys()), merge)
return list(filteredList)