Удаление пустых элементов списка python
Для начала стоит формализовать, что такое «пустой» элемент.
«Пустыми» можно считать многие элементы, например,
None, 0, 0.0, 0j, False
Если требуется выбросить из коллекции все такие элементы, то можно воспользоваться генератором списка
[value for value in values if value]
Или, если список не требуется, генераторным выражением:
(value for value in values if value)
Если правило определения «пустого» элемента более сложное, достаточно описать это правило после оператора if в указанных выше выражениях, например,
[value for value in values if value != [None]]
оставит в списке элементы, которыне не равны списку, содержащему None (важно заметить, что такой список будет пропущен в итоговый набор в первых случаях).
Как из списка удалить пустые списки?
Удалите пустые списки из списка строк
Доброго времени суток, столкнулся с такой задачей. Задача максимально лёгкая, но у меня возникли.
Удалить из заданного списка пустые списки
Помогите, пожалуйста, на Scheme: удалить из заданного списка пустые списки
Удалить все пустые элементы из списка списков
Дан список списков (List<List<string>>) , из него надо удалить все пустые списки. В простом.
Удалить из списка все элементы, содержащие пустые строки файла
в двунаправленном списке записаны данные текстового файла . удалить из списка все элементы .
4866 / 3288 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
1 2 3 4 5
>>> ls = [[], [], ['1 ', 'en', ''], ['2 '], ['3 ', '', '100'], ['4 '], ['5 '], ['6 '], ['7 '], ['8 '], []] >>> ls = list(filter(None, ls)) >>> ls [['1 ', 'en', ''], ['2 '], ['3 ', '', '100'], ['4 '], ['5 '], ['6 '], ['7 '], ['8 ']] >>>
Регистрация: 30.10.2013
Сообщений: 2
а мне тут подсказали можно сделать так, какой из вариантов оптимальней даже и не знаю
ls = [x for x in ls if x]
4866 / 3288 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
Сообщение от allozar 
какой из вариантов оптимальней даже и не знаю
выбирать нужно между filter() и включением
я сравнил через timeit: на небольших списках твой немного быстрее, а на больших списках твой медленнее в два раза
(а с del вообще в десять раз медленнее твоего)
Добавлено через 3 минуты
[guest@localhost py]$ ./timecmp.py [0.22660166999958165, 0.22645385499981785, 0.22690548299942748] [0.5606995429998278, 0.5607934289992045, 0.5594335770001635] [1.7001144109999586, 1.7018712059998506, 1.7051744469999903] [guest@localhost py]$
мой
твой
твой с del
Регистрация: 11.09.2016
Сообщений: 2
Вопрос сходный, но более глубокий.
Мне требуется из вложенных списков удалить строки типа ‘ ‘.
Фильтрация
h= filter(lambda x: x !='', b)
и перебор через IF
1 2 3 4 5 6 7 8
for w in b: for elem in w: if elem != '': b[b.index(w)][w.index(elem)]=elem elif elem == '': w.pop(w.index(elem)) else: w.remove(elem)
Как полностью убрать пустые элементы из строк?
![]()
5416 / 3840 / 1214
Регистрация: 28.10.2013
Сообщений: 9,554
Записей в блоге: 1
Могу предложить пересоздание списка.
1 2 3 4 5 6 7 8 9 10 11
ls = [[], [], ['1 ', 'en', ''], ['2 '], ['3 ', '', '100'], ['4 '], ['5 '], ['6 '], ['7 '], ['8 '],[]] ls2 = [] for i in range(len(ls)): ls2.append([]) for el in ls[i]: if el != '': ls2[i].append(el) ls = ls2 del ls2 print(ls) # [[], [], ['1 ', 'en'], ['2 '], ['3 ', '100'], ['4 '], ['5 '], ['6 '], ['7 '], ['8 '], []]
![]()
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
WhiteSadKat, через рекурсию
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
def clear(l): for e in l: if isinstance(e, list): clear(e) if isinstance(e, str) and len(e) == 0: l.remove(e) def main(): a = [1, "", 2, ["3", "", "4", ["5", "", "6"], "7"], "8", "", "9"] clear(a) print(a) if __name__ == "__main__": main()
2740 / 2339 / 620
Регистрация: 19.03.2012
Сообщений: 8,830
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
import timeit def test1(): data = [[], [], ['1 ', 'en', ''], ['2 '], ['3 ', '', '100'], ['4 '], ['5 '], ['6 '], ['7 '], ['8 '], []] for i, sequence in enumerate(data): if all(sequence): continue for j, elem in enumerate(sequence): if not elem: del data[i][j] def test2(): ls = [[], [], ['1 ', 'en', ''], ['2 '], ['3 ', '', '100'], ['4 '], ['5 '], ['6 '], ['7 '], ['8 '], []] ls2 = [] for i in range(len(ls)): ls2.append([]) for el in ls[i]: if el != '': ls2[i].append(el) ls = ls2 del ls2 def test3(): def clear(l): for e in l: if isinstance(e, list): clear(e) if isinstance(e, str) and len(e) == 0: l.remove(e) data = [[], [], ['1 ', 'en', ''], ['2 '], ['3 ', '', '100'], ['4 '], ['5 '], ['6 '], ['7 '], ['8 '], []] clear(data) print(timeit.timeit("test1()", setup="from __main__ import test1", number=100000)) print(timeit.timeit("test2()", setup="from __main__ import test2", number=100000)) print(timeit.timeit("test3()", setup="from __main__ import test3", number=100000))
Как очистить данные при помощи Pandas
Очистка данных — это процесс удаления, добавления или изменения данных для их анализа или других задач машинного обучения. Если очистить данные необходимо, начинать всегда следует с именно с этого.
Клайв Хамби сказал: «Данные — это новая нефть». И, как и нефть, они нуждаются в очистке.
Зачем нужна очистка данных?
Данные можно считать одним из самых важных активов компании. Ошибки или неточности в данных могут послужить причиной краха.
Но доступные нам данные ценны не сами по себе. Чтобы сделать их полезными, над ними нужно поработать. Например — удалить ненужные, отформатировать и модифицировать важные. В некоторых случаях для обработки данных приходится что-то добавлять. Скажем, можно добавить столбец языка, основываясь на уже имеющихся данных, или сгенерировать столбец со средним значением, основываясь на данных какого-нибудь другого столбца.
Вступление
Процесс очистки данных многоступенчатый, но не всегда необходимы все этапы.
Чтобы очистить данные, мы будем использовать язык программирования Python и библиотеку Pandas.
Python мы выбрали из-за его выразительности и доступности. Кроме того, многие эксперты выбирают этот язык для задач машинного обучения, поскольку его без проблем может изучить человек, не имеющий бэкграунда в информатике.
Что касается Pandas, это быстрая, мощная, гибкая и простая в использовании библиотека для работы с данными. Она имеет открытый код и очень популярна.
Прежде чем приступить к очистке данных, важно разобраться, какими, собственно, данными вы обладаете. Любые шаги по очистке зависят от того, что собой представляют ваши данные.
Как очистить данные: пошаговое руководство
Чтобы очистить данные, сперва их нужно правильно загрузить. В этом руководстве мы покажем базовые методы загрузки данных из CSV-файла. Больше вариантов чтения CSV вы найдете в документации.
От редакции Pythonist. На нашем сайте есть статья по этой теме — «Чтение файлов в формате CSV в Python».
import pandas as pd # 1. Чтение данных из csv - способ по умолчанию df = pd.read_csv('my_file.csv') # 2. Чтение данных из csv с использованием запятой в качестве разделителя df = pd.read_csv('my_file.csv', delimiter=',') # 3. Чтение данных из csv с использованием запятой в качестве разделителя и без заголовков df = pd.read_csv('my_file.csv', delimiter=',', header=None) # 4. Чтение данных из csv с использованием запятой в качестве разделителя и с пользовательскими заголовками my_headers = ['Id','Name', 'Type', 'Price'] df = pd.read_csv('my_file.csv', delimiter=',', header=0, names=my_headers)
Удаление дублирующихся данных
Чтобы очистить данные, некоторые шаги нужно сделать обязательно. Один из таких шагов — удаление дубликатов. И тут не важно, идет речь о текстовых или числовых данных. Если у вас слишком много дубликатов, это увеличивает время обработки данных.
# 1. Удаление дубликатов и возврат копии датафрейма df = df.drop_duplicates() # 2. Удаление дубликатов в исходном датафрейме df = df.drop_duplicates(inplace=True) # 3. Отбрасываем дубликаты, оставляя первое/последнее вхождение df = df.drop_duplicates(inplace=True, keep='last') # 4. Для нахождения дубликатов учитываем только определенные столбцы df = df.drop_duplicates(subset=['Id', 'Price'], inplace=True, keep='last')
Удаление эмодзи
Зачастую нам не нужны эмодзи в текстовых наборах данных. Мы можем их удалить всего одной строчкой кода. Сниппет, приведенный ниже, будет удалять эмодзи из датафрейма pandas столбец за столбцом. Этот сниппет можно найти на Stackoverflow.
f = df.astype(str).apply(lambda x: x.str.encode('ascii', 'ignore').str.decode('ascii'))
Здесь мы переводим все данные в значения ASCII, а те, которые не могут быть переведены, игнорируем. После перевода в значения ASCII наш код переводит данные обратно. Так мы получаем все наши данные без эмодзи.
Перевод данных в нижний регистр
Весьма вероятно, что вам придется изменить регистр данных. Здесь мы переводим их в нижний. Больше примеров можно найти в документации.
df['Type'] = df['Type'].str.lower() df['Name'] = df['Name'].str.lower()
Удаление множественных пробелов, табов и символов перевода строки
В каждом наборе данных присутствуют ненужные пробелы, табы и переходы на новую строку. Проблема в том, что табы и абзацы хорошо видно, тогда как пробелы можно не заметить, а они повлияют на обучение моделей.
df['Type'] = df['Type'].str.replace('\n', '') df['Type'] = df['Type'].str.replace('\t', ' ') df['Type'] = df['Type'].str.replace(' ', ' ', regex=True) df['Type'] = df['Type'].str.strip()
Первые две строки кода заменяют табы и символы перевода строки на пустые строки. Третья строка ищет два и более пробелов при помощи регулярного выражения, а затем заменяет их на один пробел. Наконец, последняя строка обрезает данные с обоих концов, удаляя пробелы.
Удаление URL-адресов
Для получения данных многие пользуются опросами. Но люди невнимательно заполняют поля, и порой в этих данных встречаются URL-адреса. Регулярное выражение, приведенное ниже, удаляет URL. Вы можете использовать и любой другой regex-паттерн для поиска URL. Здесь найденные адреса заменяются пустой строкой.
df['Type'] = df['Type'].replace(r'http\S+', '', regex=True).replace(r'www\S+', '', regex=True)
Отбрасываем строки с пустыми данными
После выполнения предыдущих шагов по очистке в столбцах остаются пустые данные. От этих пустых строк нужно избавиться, иначе это создаст неопределенность при обучении модели. Чтобы удалить все строки с пустыми данными, мы используем два метода:
df.dropna() df['Type'].astype(bool) df = df[df['Type'].astype(bool)]
Первая строка кода удаляет все строки, содержащие np.nan , pd.NaT и None . Остальные удаляют строки, содержащие символы пустой строки. Второй метод быстрый, но если в столбце будет хотя бы пробел, он не сработает. Это еще одна причина обрезать лишние пробелы заранее.
Дальнейшая обработка данных
Иногда, чтобы очистить данные, бывает нужно отбросить некоторые столбцы, создать новый столбец из существующих данных или удалить строки, не содержащие определенных данных.
import numpy as np df = df.drop(['Id', 'Name'], axis=1) df = df[df['Type'].str.contains('frozen') | df['Type'].str.contains('green')] def detect_price(row): if row['Price'] > 15.50: return 'High' elif row['Price'] > 5.50 and row['Price'] 0.0 and row['Price']
Здесь в третьей строке мы отбрасываем два столбца с именами Id и Name и возвращаем копию нового датафрейма.
Четвертая строка проверяет, содержит ли столбец Type строку frozen или green , затем возвращает True и сохраняет эту строку.
Строки с 7 по 17 создают новый столбец с именем Range на основе данных столбца Price . Используя лямбда-функцию, мы передаем каждую строку в функцию detect_price и возвращаем значение на основе цены. Затем возвращаемое значение присваивается новому столбцу в строке, переданной в функцию. Мы используем np.NaN , чтобы потом иметь возможность удалить эти строки при помощи df.dropna() .
Заключение
Процесс очистки данных — один из многих процессов, связанных с data science. Очищать и обрабатывать данные в каждом отдельном проекте нужно по-разному. В этой статье мы рассмотрели несколько методов очистки из числа самых востребованных. Вы можете создать собственный набор методов или использовать любой из множества существующих. Весь код можно посмотреть по ссылке.
REF: Шпаргалка по Python
Автоматически вычисляются к False: None, 0 (целое), 0.0 (вещественное), пустые строки и объекты контейнерных типов. Оператор and обладает приоритетом перед or.
Строки
st, s = "aaa", 'aa' st.strip() # удаляем пробелы вначале и конце (возврат новой строки) st.lower() # в нижний регистр st.upper() # в вехний регистр st.startswith(s) # начинается со строки s (True, False) st.endswith(s) # заканчивается строкой s (True, False) st.find(s) # индекс найденного вхождения (int) s in st # s содержится в st (True, False) st.replace(s1,s2) # заменить все s1 на s2 ','.join(["F", "B", "I"]) # cклеить элементы списка с разделителем
Память
Строки, числа - неизменяемые объекты
y = x = 3 s1, s2, i1, i2 = "aaa", "aaa", 1, 1 x is y # True (ссылаются на одну память) s1 is s2 # True i1 is i2 # True [3] is [3] # False id(x) # 2546626711664 (адрес в памяти)
Списки
lst = [1, 2, 3] lst.append(4) # [1, 2, 3, 4] ничего не возращает (в нём же) lst.insert(2, 4) # [1, 2, 4, 3] (на 2-ю позицию, сдвигая вправо) [1, 2, 3] + [4, 5] # [1, 2, 3, 4, 5] конкатенация lst.extend([4, 5]) # тоже но эффективнее (?) lst.pop() # 4 [1, 2, 3] удалить последний, вернув его lst.pop(1) # 2 [1, 3, 4] удалить второй lst[1], вернув его lst.remove(2) # удаляет первую 2-ку (если нет - будет исключение) lst.reverse() # перевернуть список 1 in lst # есть или нет в списке lst.sort() # лексографически сортировать (элементы сравнимы) lst.sort(reverse = True) # в обратном порядке lst.sort(key = lambda x: x%2) # [1,2,3,4] -> [2,4,1,3] lst = list( filter(lambda x: x % 2, lst) )# [1,2,3,4] -> [1,3] lst = list( filter(None, tokens) ) # ['a','','b'] -> ['a','b'] убрать пустые строки
Множество
Элементы должны быть хешируемыми (числа, строки, но не списки)
hash('a') # -5021022557028035767 s = # порядок не определён, значения уникальны 'a' in s # принадлежность
Ассоциативные массивы
Выполняет операцию t[hash('x')] и проверяет, не равно ли None возвращаемое значение.
t = t['x'] = 3 # если ключа 'x' нет - исключение, иначе значение t.get('x') # None если нет, иначе значение 'x' in t # есть ли ключ t.keys(), t.values() # ключи, значения for k, v in t.items(): # пары ключ-значение print(k) if v > 5 else None
Управление и функции
Циклы и ветвления
for i in [0, 1, 2]: j = 0 if x > 3: print("Big") print(i) while j < 3: elif x == 3: print("Medium") j = j + 1 else: print("Small")
Функции
def f(x, y=2): return x*y f = lambda x,y: x+y # lambda аргументы : возвращаемое выражение z = f(2,3)
Списковое включение и map
lst = [x**2 for x in range(10)] lst = [(1,2), (3,4)] [x for x,y in lst if y > 2] # [1] [(x, y) for x in range(3) for y in range(3)]) ([line.strip() for line in open("readFile.py")] [[x for x in line.split() if len(x) > 3] for line in text.split('\n')]
Функция map() применяет функцию к каждому элементу итерируемого объекта. Если объектов несколько, остановит расчеты после достижения конца наиболее короткого объекта:
list(map(lambda x: 2*x, [1,2,3])) # [2, 4, 6] txt = ['girl like boy', 'boy is programmer'] mark = list( map(lambda s: (True, s) if 'girl' in s else (False, s), txt) ) powers = list(map(pow, [2,3], [1, 2, 3])) # [2, 9] = 2**1, 3**2
Срезы
s = [0, 1, 2, 3, 4] # список s[:] # копия списка (новая память) s[1:] # [1, 2, 3, 4] все, кроме первого s[-3:] # [2, 3, 4] последние 3 s[1:4:2] # [1, 3] с шагом 2 del s[1:3] # s = [0, 3, 4] удаление s[1:4:2]=list("ab") # s = [0,'a',2,'b',4] замена "Hello!"[2:4] # 'll' списки, строки, кортежи "Hello!"[::-1] # '!olleH' переворот
Чтобы объекты понимали срезы (slice), необходимо определить методы __getitem__, __setitem__, __delitem__ (атрибуты key могут быть None, надо проверять):
class MySliceble(): def __getitem__(self, key): if isinstance(key, slice): return list(range(key.start, key.stop, key.step)) else: raise Exception("Trying to access by index") my = MySliceble() my[2:9:2] # [2, 4, 6, 8]
