У меня есть файл, pd.DataFrame
который был создан путем анализа некоторых таблиц Excel. Столбец, в котором есть пустые ячейки. Например, ниже приведены выходные данные для частоты этого столбца, 32320 записей имеют пропущенные значения для Tenant .
>>> value_counts(Tenant, normalize=False)
32320
Thunderhead 8170
Big Data Others 5700
Cloud Cruiser 5700
Partnerpedia 5700
Comcast 5700
SDP 5700
Agora 5700
dtype: int64
Я пытаюсь удалить строки, в которых отсутствует Tenant, однако .isnull()
опция не распознает отсутствующие значения.
>>> df['Tenant'].isnull().sum()
0
Столбец имеет тип данных «Объект». Что в этом случае происходит? Как я могу удалить записи, в которых отсутствует арендатор ?
np.nan
когда это возможноpd.np.nan
?df[df['Tenant'].astype(bool)]
(при условии отсутствия пробельных символов - только пустая строка) быстрее, чемdf.replace('', np.nan).dropna(subset=['Tenant'])
Pythonic + Pandorable:
df[df['col'].astype(bool)]
Пустые строки являются ложными, что означает, что вы можете фильтровать значения типа bool следующим образом:
df = pd.DataFrame({ 'A': range(5), 'B': ['foo', '', 'bar', '', 'xyz'] }) df A B 0 0 foo 1 1 2 2 bar 3 3 4 4 xyz
df['B'].astype(bool) 0 True 1 False 2 True 3 False 4 True Name: B, dtype: bool df[df['B'].astype(bool)] A B 0 0 foo 2 2 bar 4 4 xyz
Если ваша цель - удалить не только пустые строки, но и строки, содержащие только пробелы, используйте
str.strip
заранее:df[df['B'].str.strip().astype(bool)] A B 0 0 foo 2 2 bar 4 4 xyz
Быстрее, чем вы думаете
.astype
является векторизованной операцией, это быстрее, чем все варианты, представленные до сих пор. По крайней мере, из моих тестов. YMMV.Вот сравнение времени, я добавил несколько других методов, которые я мог придумать.
Код тестирования, для справки:
import pandas as pd import perfplot df1 = pd.DataFrame({ 'A': range(5), 'B': ['foo', '', 'bar', '', 'xyz'] }) perfplot.show( setup=lambda n: pd.concat([df1] * n, ignore_index=True), kernels=[ lambda df: df[df['B'].astype(bool)], lambda df: df[df['B'] != ''], lambda df: df[df['B'].replace('', np.nan).notna()], # optimized 1-col lambda df: df.replace({'B': {'': np.nan}}).dropna(subset=['B']), ], labels=['astype', "!= ''", "replace + notna", "replace + dropna", ], n_range=[2**k for k in range(1, 15)], xlabel='N', logx=True, logy=True, equality_check=pd.DataFrame.equals)
источник
value_counts по умолчанию опускает NaN, поэтому вы, скорее всего, имеете дело с "".
Так что вы можете просто отфильтровать их, как
filter = df["Tenant"] != "" dfNew = df[filter]
источник
Есть ситуация, когда в ячейке есть белое пространство, вы его не видите, используйте
df['col'].replace(' ', np.nan, inplace=True)
чтобы заменить пробел на NaN, затем
df= df.dropna(subset=['col'])
источник
Вы можете использовать этот вариант:
import pandas as pd vals = { 'name' : ['n1', 'n2', 'n3', 'n4', 'n5', 'n6', 'n7'], 'gender' : ['m', 'f', 'f', 'f', 'f', 'c', 'c'], 'age' : [39, 12, 27, 13, 36, 29, 10], 'education' : ['ma', None, 'school', None, 'ba', None, None] } df_vals = pd.DataFrame(vals) #converting dict to dataframe
Это выведет (** - выделение только желаемых строк):
age education gender name 0 39 ma m n1 ** 1 12 None f n2 2 27 school f n3 ** 3 13 None f n4 4 36 ba f n5 ** 5 29 None c n6 6 10 None c n7
Чтобы отказаться от всего, что не имеет значения «образование», используйте приведенный ниже код:
df_vals = df_vals[~df_vals['education'].isnull()]
('~' означает НЕ)
Результат:
age education gender name 0 39 ma m n1 2 27 school f n3 4 36 ba f n5
источник